Repository: QualitySolution/Workwear
Pull request #606: Добавление документа поставки (закупки).
Author: login: Katetim32
Created: 2025-02-25T11:13:33Z | Merged: 2025-03-11T07:31:45Z



Diff:
diff --git a/QSProjects b/QSProjects
index bc32239d6..7b5007e2f 160000
--- a/QSProjects
+++ b/QSProjects
@@ -1 +1 @@
-Subproject commit bc32239d6107df1b9b14f4f59dc5505156635ee2
+Subproject commit 7b5007e2f567bf1e0c29c5588eba92c94685220a
diff --git a/Workwear.Core/Domain/Supply/ShipmentStatus.cs b/Workwear.Core/Domain/Supply/ShipmentStatus.cs
new file mode 100644
index 000000000..67932a69b
--- /dev/null
+++ b/Workwear.Core/Domain/Supply/ShipmentStatus.cs
@@ -0,0 +1,17 @@
+﻿using System.ComponentModel.DataAnnotations;
+
+namespace Workwear.Domain.Supply {
+	public enum ShipmentStatus {
+		[Display(Name="Заказано")]
+		Ordered,
+		[Display(Name = "В пути")]
+		OnTheWay,
+		[Display(Name="Ожидает оплаты")]
+		AwaitPayment,
+		[Display(Name="Отменено")]
+		Cancelled,
+		[Display(Name = "Получено")]
+		Received
+	
+	}
+}
diff --git a/Workwear.Desktop/ConfigureDeletion.cs b/Workwear.Desktop/ConfigureDeletion.cs
index 70531d97d..cc3da88e8 100644
--- a/Workwear.Desktop/ConfigureDeletion.cs
+++ b/Workwear.Desktop/ConfigureDeletion.cs
@@ -12,6 +12,7 @@
 using Workwear.Domain.Statements;
 using Workwear.Domain.Stock;
 using Workwear.Domain.Stock.Documents;
+using Workwear.Domain.Supply;
 using Workwear.Domain.Users;
 
 namespace Workwear
@@ -371,6 +372,11 @@ public static void ConfigureDeletion ()
 			DeleteConfig.AddHibernateDeleteInfo<CausesWriteOff>()
 				.AddClearDependence<WriteoffItem>(x => x.CausesWriteOff);
 			
+			#endregion
+			#region Документ планируемой поставки
+			DeleteConfig.AddHibernateDeleteInfo<Shipment>()
+				.AddDeleteDependence<ShipmentItem>(x => x.Shipment);
+			DeleteConfig.AddHibernateDeleteInfo<ShipmentItem>();
 			#endregion
 			#region Пользователь
 
diff --git a/Workwear.Desktop/Domain/Supply/Shipment.cs b/Workwear.Desktop/Domain/Supply/Shipment.cs
new file mode 100644
index 000000000..66586e2d4
--- /dev/null
+++ b/Workwear.Desktop/Domain/Supply/Shipment.cs
@@ -0,0 +1,140 @@
+﻿using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using Gamma.Utilities;
+using QS.Dialog;
+using QS.DomainModel.Entity;
+using QS.Extensions.Observable.Collections.List;
+using QS.HistoryLog;
+using QS.Project.Domain;
+using Workwear.Domain.Sizes;
+using Workwear.Domain.Stock;
+
+namespace Workwear.Domain.Supply {
+	[Appellative(Gender = GrammaticalGender.Feminine,
+		NominativePlural = "планируемые поставки",
+		Nominative = "планируемая поставка",
+		Genitive = "планируемой поставки"
+	)]
+	[HistoryTrace]
+	public class Shipment: PropertyChangedBase, IDomainObject, IValidatableObject {
+		private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger ();
+		#region Свойства
+
+		public virtual int Id { get; set; }
+		
+		private DateTime startPeriod = DateTime.Today;
+		[Display(Name="Начало периода")]
+		public virtual DateTime StartPeriod {
+			get=> startPeriod;
+			set {startPeriod = value;}
+		}
+		
+		private DateTime endPeriod = DateTime.Today.AddDays(1);
+		[Display(Name="Окончание периода")]
+		public virtual DateTime EndPeriod {
+			get=> endPeriod;
+			set { endPeriod = value; }
+		}
+		
+		private UserBase createdbyUser;
+		[Display(Name = "Документ создал")]
+		public virtual UserBase CreatedbyUser {
+			get =>createdbyUser; 
+			set { createdbyUser = value; }
+		}
+		
+		private string comment;
+		[Display(Name = "Комментарий")]
+		public virtual string Comment {
+			get =>comment;
+			set { comment = value; }
+		}
+		
+		private DateTime creationDate = DateTime.Now;
+		[Display(Name = "Дата создания")]
+		public virtual DateTime CreationDate {
+			get => creationDate;
+			set {creationDate = value;}
+		}
+		
+		private IObservableList<ShipmentItem> items = new ObservableList<ShipmentItem>();
+
+		[Display(Name = "Строки документа")]
+		public virtual IObservableList<ShipmentItem> Items {
+			get=>items;
+			set { items = value; }
+		}
+
+		private ShipmentStatus status;
+
+		[Display(Name = "Статус поставки")]
+		public virtual ShipmentStatus Status {
+			get=>status;
+			set{status=value;}
+		}
+
+		#endregion
+
+		public virtual string Title => $"Планируемая поставка № {Id.ToString()} в период с {StartPeriod:d} по {EndPeriod:d}";
+		#region IValidatableObject implementation
+		public virtual IEnumerable<ValidationResult> Validate(ValidationContext validationContext) {
+			if (StartPeriod < new DateTime(2025, 1, 1))
+				yield return new ValidationResult ("Период должен быть указан (не ранее 2025-го)", 
+					new[] { this.GetPropertyName (o => o.StartPeriod)});
+			if(StartPeriod > EndPeriod)
+				yield return new ValidationResult("Дата начала периода должна быть меньше его окончания",
+					new[] { this.GetPropertyName(o => o.StartPeriod) });
+			if(Items.Count == 0)
+				yield return new ValidationResult ("Поставка должна содержать хотя бы одну строку.", 
+					new[] { this.GetPropertyName (o => o.Items)});
+
+			if(Items.Any (i => i.Amount <= 0))
+				yield return new ValidationResult ("Поставка не должна содержать строк с нулевым количеством.", 
+					new[] { this.GetPropertyName (o => o.Items)});
+			
+			
+		}
+		#endregion
+
+		#region Строки документа
+
+		public virtual ShipmentItem AddItem(Nomenclature nomenclature, IInteractiveMessage message) {
+			var newItem = new ShipmentItem(this) {
+				Amount = 1,
+				Nomenclature = nomenclature,
+				Cost = nomenclature.SaleCost ?? 0m,
+			};
+			Items.Add(newItem);
+			return newItem;
+		}
+
+		public virtual ShipmentItem AddItem(Nomenclature nomenclature, Size size, Size height, int amount = 0, decimal price = 0m) {
+			var item = FindItem(nomenclature,size,height);
+			if(item == null) {
+				item = new ShipmentItem(this) {
+					Amount = amount,
+					Nomenclature = nomenclature,
+					WearSize = size,
+					Height = height,
+					Cost = price
+				};
+				Items.Add(item);
+			}
+			else {
+				item.Amount += amount;
+			}
+			return item;
+		}
+
+		public virtual void RemoveItem(ShipmentItem item) {
+			Items.Remove(item);
+		}
+
+		public virtual ShipmentItem FindItem(Nomenclature nomenclature, Size size, Size height) =>Items.
+			FirstOrDefault(i=>i.Nomenclature.Id == nomenclature.Id && i.Height==height&&i.WearSize==size);
+
+		#endregion
+	}
+}
diff --git a/Workwear.Desktop/Domain/Supply/ShipmentItem.cs b/Workwear.Desktop/Domain/Supply/ShipmentItem.cs
new file mode 100644
index 000000000..4e850f0b2
--- /dev/null
+++ b/Workwear.Desktop/Domain/Supply/ShipmentItem.cs
@@ -0,0 +1,111 @@
+﻿using System.ComponentModel.DataAnnotations;
+using QS.BusinessCommon.Domain;
+using QS.DomainModel.Entity;
+using QS.HistoryLog;
+using Workwear.Domain.Sizes;
+using Workwear.Domain.Stock;
+
+namespace Workwear.Domain.Supply{
+	[Appellative (Gender = GrammaticalGender.Feminine,
+		NominativePlural = "строки предполагаемой поставки",
+		Nominative = "строка предполагаемой поставки",
+		Genitive = "строки предполагаемой поставки"
+	)]
+	[HistoryTrace]
+	public class ShipmentItem: IDomainObject 
+	{
+		#region Свойства
+		public virtual int Id { get; set; }
+		
+		private Shipment shipment;
+		
+		[Display(Name = "Документ")]
+		[IgnoreHistoryTrace]
+		public virtual Shipment Shipment {
+			get => shipment;
+			set {shipment = value;}
+		}
+		
+		Nomenclature nomenclature;
+		[Display (Name = "Номенклатура")]
+		public virtual Nomenclature Nomenclature {
+			get => nomenclature;
+			set { nomenclature = value; }
+		}
+		
+		[Display (Name = "Наименование")]
+		public virtual string ItemName {
+			get => nomenclature?.Name; 
+		}
+		
+		[Display(Name = "Тип Роста")]
+		public virtual SizeType HeightType {
+			get => nomenclature?.Type.HeightType;
+		}
+		
+		[Display(Name = "Тип размера одежды")]
+		public virtual SizeType WearSizeType {
+			get => nomenclature?.Type.SizeType;
+		}
+		
+		[Display(Name = "Единица измерения")]
+		public virtual MeasurementUnits Units {
+			get => nomenclature?.Type.Units; 
+		}
+		
+		private int amount;
+		[Display (Name = "Количество")]
+		[PropertyChangedAlso("Total")]
+		public virtual int Amount {
+			get => amount;
+			set {amount = value; }
+		}
+
+		private decimal cost;
+		[Display (Name = "Цена")]
+		[PropertyChangedAlso("Total")]
+		public virtual decimal Cost {
+			get => cost;
+			set { cost = value; }
+		}
+		
+		private Size wearSize;
+		[Display(Name = "Размер")]
+		public virtual Size WearSize {
+			get => wearSize;
+			set => wearSize = value;
+		}
+		
+		private Size height;
+		[Display(Name = "Рост одежды")]
+		public virtual Size Height {
+			get => height;
+			set => height = value;
+		}
+		
+		private string comment;
+		[Display(Name = "Комментарий")]
+		public virtual string Comment {
+			get =>comment;
+			set { comment = value; }
+		}
+		#endregion
+		
+		#region Расчетные
+
+		public virtual string Title => $"Закупка {Nomenclature?.Name} в количестве {Amount} {Nomenclature?.Type?.Units?.Name}";
+		public virtual decimal Total => Cost * Amount;
+		public virtual StockPosition StockPosition => 
+			new StockPosition(Nomenclature, 0m,WearSize, Height, Owner);
+
+		public virtual Owner Owner { get; set; }
+
+		#endregion
+
+		public ShipmentItem(){ }
+
+		public ShipmentItem(Shipment shipment) {
+			this.shipment = shipment;
+		}
+	}
+}
diff --git a/Workwear.Desktop/HibernateMapping/Supply/ShipmentItemMap.cs b/Workwear.Desktop/HibernateMapping/Supply/ShipmentItemMap.cs
new file mode 100644
index 000000000..d2c3031f1
--- /dev/null
+++ b/Workwear.Desktop/HibernateMapping/Supply/ShipmentItemMap.cs
@@ -0,0 +1,24 @@
+﻿using FluentNHibernate.Mapping;
+using Workwear.Domain.Supply;
+
+namespace Workwear.HibernateMapping.Supply {
+	public class ShipmentItemMap:ClassMap<ShipmentItem> {
+		public ShipmentItemMap() {
+			Table("shipment_items");
+			
+			if(Workwear.HibernateMapping.MappingParams.UseIdsForTest)
+				Id (x => x.Id).Column ("id").GeneratedBy.HiLo("0");
+			else 
+				Id (x => x.Id).Column ("id").GeneratedBy.Native();
+			
+			Map(x=>x.Amount).Column ("quantity");
+			Map(x => x.Cost).Column ("cost");
+			Map(x=>x.Comment).Column("comment");
+			
+			References(x=>x.Shipment).Column("shipment_id");
+			References(x=>x.Nomenclature).Column("nomenclature_id");
+			References(x=>x.WearSize).Column("size_id");
+			References(x=>x.Height).Column("height_id");
+		}
+	}
+}
diff --git a/Workwear.Desktop/HibernateMapping/Supply/ShipmentMap.cs b/Workwear.Desktop/HibernateMapping/Supply/ShipmentMap.cs
new file mode 100644
index 000000000..a64d38cf7
--- /dev/null
+++ b/Workwear.Desktop/HibernateMapping/Supply/ShipmentMap.cs
@@ -0,0 +1,30 @@
+﻿using FluentNHibernate.Mapping;
+using Workwear.Domain.Supply;
+
+namespace Workwear.HibernateMapping.Supply {
+	public class ShipmentMap : ClassMap<Shipment> {
+		public ShipmentMap() {
+			Table("shipment");
+
+			if(MappingParams.UseIdsForTest)
+				Id(x => x.Id).Column("id").GeneratedBy.HiLo("0");
+			else
+				Id(x => x.Id).Column("id").GeneratedBy.Native();
+
+			Map(x => x.StartPeriod).Column("start_period");
+			Map(x => x.EndPeriod).Column("end_period");
+			Map(x=>x.Status).Column("status");
+			Map(x => x.Comment).Column("comment");
+			Map(x => x.CreationDate).Column("creation_date");
+
+			References(x => x.CreatedbyUser).Column("user_id");
+
+			HasMany(x => x.Items)
+				.Inverse()
+				.KeyColumn("shipment_id").Not.KeyNullable()
+				.Cascade.AllDeleteOrphan()
+				.LazyLoad();
+
+		}
+	}
+}
diff --git a/Workwear.Sql/Scripts/2.9.2.sql b/Workwear.Sql/Scripts/2.9.2.sql
new file mode 100644
index 000000000..5b92e7789
--- /dev/null
+++ b/Workwear.Sql/Scripts/2.9.2.sql
@@ -0,0 +1,53 @@
+﻿-- Документ закупки
+create table shipment
+(
+    id int unsigned auto_increment primary key,
+    start_period date not null,
+    end_period date not null,
+	status enum('Ordered','OnTheWay', 'AwaitPayment','Cancelled','Received') not null default 'Ordered',
+    user_id int unsigned null,
+    comment text null,
+    creation_date datetime null
+);
+create index index_shipment_start_period
+    on shipment (start_period);
+create index index_shipment_end_period
+    on shipment (end_period);
+
+-- Строки документа закупки
+create table shipment_items
+(
+    id int unsigned auto_increment primary key,
+    shipment_id int unsigned not null,
+    nomenclature_id int unsigned not null,
+    quantity int unsigned not null,
+    cost decimal(10, 2) unsigned default 0.00 not null,
+    size_id int unsigned null,
+    height_id int unsigned null,
+    comment varchar(120) null,
+    constraint fk_shipment_items_doc
+        foreign key (shipment_id) references shipment (id)
+            on update cascade on delete cascade,
+    constraint fk_shipment_items_nomenclature
+        foreign key (nomenclature_id) references nomenclature (id)
+            on update cascade,
+    constraint fk_shipment_items_size_id
+        foreign key (size_id) references sizes (id)
+            on update cascade,
+    constraint fk_shipment_items_height_id
+        foreign key (height_id) references sizes (id)
+            on update cascade
+);
+create index index_shipment_items_doc
+    on shipment_items (shipment_id);
+
+create index index_shipment_items_height
+    on shipment_items (height_id);
+
+create index index_shipment_items_nomenclature
+    on shipment_items (nomenclature_id);
+
+create index index_shipment_items_size
+    on shipment_items (size_id);
+
+
diff --git a/Workwear.Sql/Scripts/2.9.sql b/Workwear.Sql/Scripts/2.9.sql
index 4db9bb8bc..44423e179 100644
--- a/Workwear.Sql/Scripts/2.9.sql
+++ b/Workwear.Sql/Scripts/2.9.sql
@@ -727,3 +727,8 @@ alter table stock_income
 
 drop table stock_income_detail;
 
+
+
+
+
+
diff --git a/Workwear.Sql/Scripts/new_empty.sql b/Workwear.Sql/Scripts/new_empty.sql
index cabf4cd50..2dd982cd5 100644
--- a/Workwear.Sql/Scripts/new_empty.sql
+++ b/Workwear.Sql/Scripts/new_empty.sql
@@ -2339,6 +2339,62 @@ create index fk_stock_expense_duty_norm_items_warehouse_operation_idx
 	on stock_expense_duty_norm_items (warehouse_operation_id);
 create index fk_stock_expense_duty_norm_items_stock_expense_duty_norm_idx
 	on stock_expense_duty_norm_items (stock_expense_duty_norm_id);
+
+-- Table `shipment`
+
+create table shipment
+(
+	id int unsigned auto_increment primary key,
+	start_period date not null,
+	end_period date not null,
+	status enum('Ordered','OnTheWay', 'AwaitPayment','Cancelled','Received') not null default 'Ordered',
+	user_id int unsigned null,
+	comment text null,
+	creation_date datetime null
+);
+create index index_shipment_start_period
+	on shipment (start_period);
+create index index_shipment_end_period
+	on shipment (end_period);
+
+-- Table `shipment_items`
+
+create table shipment_items
+(
+	id int unsigned auto_increment primary key,
+	shipment_id int unsigned not null,
+	nomenclature_id int unsigned not null,
+	quantity int unsigned not null,
+	cost decimal(10, 2) unsigned default 0.00 not null,
+	size_id int unsigned null,
+	height_id int unsigned null,
+	comment varchar(120) null,
+	constraint fk_shipment_items_doc
+		foreign key (shipment_id) references shipment (id)
+			on update cascade on delete cascade,
+	constraint fk_shipment_items_nomenclature
+		foreign key (nomenclature_id) references nomenclature (id)
+			on update cascade,
+	constraint fk_shipment_items_size_id
+		foreign key (size_id) references sizes (id)
+			on update cascade,
+	constraint fk_shipment_items_height_id
+		foreign key (height_id) references sizes (id)
+			on update cascade
+);
+create index index_shipment_items_doc
+	on shipment_items (shipment_id);
+
+create index index_shipment_items_height
+	on shipment_items (height_id);
+
+create index index_shipment_items_nomenclature
+	on shipment_items (nomenclature_id);
+
+create index index_shipment_items_size
+	on shipment_items (size_id);
+	
+
 -- -----------------------------------------------------
 -- function count_issue
 -- -----------------------------------------------------
@@ -2397,7 +2453,7 @@ SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
 -- -----------------------------------------------------
 START TRANSACTION;
 INSERT INTO `base_parameters` (`name`, `str_value`) VALUES ('product_name', 'workwear');
-INSERT INTO `base_parameters` (`name`, `str_value`) VALUES ('version', '2.9.1');
+INSERT INTO `base_parameters` (`name`, `str_value`) VALUES ('version', '2.9.2');
 INSERT INTO `base_parameters` (`name`, `str_value`) VALUES ('DefaultAutoWriteoff', 'True');
 
 COMMIT;
@@ -2912,3 +2968,4 @@ INSERT INTO `size_suitable` (`size_id`, `size_suitable_id`) VALUES (140, 104);
 
 COMMIT;
 
+
diff --git a/Workwear/Journal/JournalsColumnsConfigs.cs b/Workwear/Journal/JournalsColumnsConfigs.cs
index 7842b8907..1dd587a9c 100644
--- a/Workwear/Journal/JournalsColumnsConfigs.cs
+++ b/Workwear/Journal/JournalsColumnsConfigs.cs
@@ -6,6 +6,7 @@
 using QS.Cloud.Postomat.Manage;
 using QS.Journal.GtkUI;
 using QS.Utilities.Numeric;
+using Workwear.Domain.Supply;
 using Workwear.Journal.ViewModels.Analytics;
 using workwear.Journal.ViewModels.ClothingService;
 using workwear.Journal.ViewModels.Communications;
@@ -14,6 +15,7 @@
 using workwear.Journal.ViewModels.Regulations;
 using workwear.Journal.ViewModels.Statements;
 using workwear.Journal.ViewModels.Stock;
+using workwear.Journal.ViewModels.Supply;
 using workwear.Journal.ViewModels.Tools;
 using Workwear.Tools.Features;
 
@@ -508,6 +510,32 @@ string ForegroundColor(EmployeeJournalNode n)
 					.Finish()
 			);
 			#endregion
+
+			#region Supply
+
+			TreeViewColumnsConfigFactory.Register<ShipmentJournalViewModel>(
+				(jvm) => FluentColumnsConfig<ShipmentJournalNode>.Create()
+					.AddColumn("ИД").AddTextRenderer(node => $"{node.Id}").SearchHighlight()
+					.AddColumn("Период").AddTextRenderer(node=>$"{node.StartPeriod.ToShortDateString()} - {node.EndPeriod.ToShortDateString()}")
+					.AddColumn("Создал").AddTextRenderer(node=>node.Author).SearchHighlight()
+					.AddColumn("Дата создания").AddTextRenderer(node=>node.CreationDate.ToShortDateString())
+					.AddColumn("Комментарий").AddTextRenderer(node=>node.Comment).SearchHighlight()
+					.AddColumn("Статус").AddTextRenderer(node=>node.StatusText)
+					.RowCells().AddSetter<Gtk.CellRendererText>((c, x) => c.Foreground = ForegroundColorShipment(x))
+					.Finish()
+				);
+			string ForegroundColorShipment(ShipmentJournalNode n)
+			{
+				if(n.Status==ShipmentStatus.Cancelled||n.Status==ShipmentStatus.Received)
+					return "gray";
+				if(n.EndPeriod < DateTime.Today)
+					return "red";
+				if(n.StartPeriod<=DateTime.Today&&n.EndPeriod>=DateTime.Today)
+					return "orange";
+				return "black";
+			}
+
+			#endregion
 		}
 	}
 }
diff --git a/Workwear/Journal/ViewModels/Supply/ShipmentJournalViewModel.cs b/Workwear/Journal/ViewModels/Supply/ShipmentJournalViewModel.cs
new file mode 100644
index 000000000..75383d4a8
--- /dev/null
+++ b/Workwear/Journal/ViewModels/Supply/ShipmentJournalViewModel.cs
@@ -0,0 +1,77 @@
+﻿using System;
+using Gamma.ColumnConfig;
+using Gamma.Utilities;
+using NHibernate;
+using NHibernate.Transform;
+using QS.Dialog;
+using QS.DomainModel.UoW;
+using QS.Navigation;
+using QS.Project.Domain;
+using QS.Project.Journal;
+using QS.Project.Services;
+using QS.Services;
+using Workwear.Domain.Supply;
+using Workwear.Tools.Features;
+using Workwear.ViewModels.Supply;
+
+namespace workwear.Journal.ViewModels.Supply {
+	public class ShipmentJournalViewModel: EntityJournalViewModelBase<Shipment, ShipmentViewModel, ShipmentJournalNode> {
+		public FeaturesService FeaturesService { get; }
+
+		public ShipmentJournalViewModel(
+			IUnitOfWorkFactory unitOfWorkFactory,
+			IInteractiveService interactiveService,
+			INavigationManager navigationManager,
+			FeaturesService featuresService,
+			IDeleteEntityService deleteEntityService = null,
+			ICurrentPermissionService currentPermissionService = null
+		) : base(unitOfWorkFactory, interactiveService, navigationManager, deleteEntityService, currentPermissionService) 
+		{
+			FeaturesService = featuresService ?? throw new ArgumentNullException(nameof(featuresService));
+			
+			TableSelectionMode = JournalSelectionMode.Multiple;
+			
+		}
+
+		protected override IQueryOver<Shipment> ItemsQuery(IUnitOfWork uow) {
+			ShipmentJournalNode resultAlias = null;
+			Shipment shipmentAlias = null;
+			UserBase authorAlias = null;
+
+			var query = uow.Session.QueryOver<Shipment>(() => shipmentAlias);
+			return query
+				.Where(GetSearchCriterion(
+					() => shipmentAlias.Id, 
+						()=>authorAlias.Name,
+						()=>shipmentAlias.Comment)
+				)
+				.JoinAlias(()=>shipmentAlias.CreatedbyUser, ()=>authorAlias, NHibernate.SqlCommand.JoinType.LeftOuterJoin)
+				.SelectList((list) => list
+					.Select(x => x.Id).WithAlias(() => resultAlias.Id)
+					.Select(x => x.StartPeriod).WithAlias(() => resultAlias.StartPeriod)
+					.Select(x => x.EndPeriod).WithAlias(() => resultAlias.EndPeriod)
+					.Select(x=>shipmentAlias.Status).WithAlias(() => resultAlias.Status)
+					.Select(x => authorAlias.Name).WithAlias(() => resultAlias.Author)
+					.Select(x => x.CreationDate).WithAlias(() => resultAlias.CreationDate)
+					.Select(x => x.Comment).WithAlias(() => resultAlias.Comment)
+				).OrderBy(x => x.StartPeriod).Desc
+				.TransformUsing(Transformers.AliasToBean<ShipmentJournalNode>());
+		}
+		
+	}
+
+	public class ShipmentJournalNode {
+		[SearchHighlight]
+		public int Id { get; set; }
+		public DateTime StartPeriod { get; set; }
+		public DateTime EndPeriod { get; set; }
+		public ShipmentStatus Status { get; set; }
+		public string StatusText => Status.GetEnumTitle();
+		[SearchHighlight]
+		public string Author { get; set; }
+		public DateTime CreationDate { get; set; }
+		[SearchHighlight]
+		public String Comment { get; set; }
+		
+	}
+}
diff --git a/Workwear/MainWindow.cs b/Workwear/MainWindow.cs
index fe6c41d0e..d90f02200 100644
--- a/Workwear/MainWindow.cs
+++ b/Workwear/MainWindow.cs
@@ -72,6 +72,7 @@
 using Workwear;
 using workwear.Journal.Filter.ViewModels.Stock;
 using Workwear.Journal.ViewModels.Analytics;
+using workwear.Journal.ViewModels.Supply;
 using Workwear.Repository.Company;
 using Workwear.ViewModels.Export;
 using CurrencyWorks = QS.Utilities.CurrencyWorks;
@@ -1000,4 +1001,8 @@ protected void OnActionWarehouseTransferReportActivated(object sender, EventArgs
 	protected void OnActionWearCardsReportActivated(object sender, EventArgs e) {
 		NavigationManager.OpenViewModel<RdlViewerViewModel, Type>(null, typeof(WearCardsReportViewModel));
 	}
+
+	protected void OnActionShipmentActivated(object sender, EventArgs e) {
+		NavigationManager.OpenViewModel<ShipmentJournalViewModel>(null);
+	}
 }
diff --git a/Workwear/ViewModels/Supply/ShipmentViewModel.cs b/Workwear/ViewModels/Supply/ShipmentViewModel.cs
new file mode 100644
index 000000000..6b7e43cb4
--- /dev/null
+++ b/Workwear/ViewModels/Supply/ShipmentViewModel.cs
@@ -0,0 +1,162 @@
+﻿using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using Autofac;
+using QS.Dialog;
+using QS.DomainModel.Entity;
+using QS.DomainModel.UoW;
+using QS.Extensions.Observable.Collections.List;
+using QS.Navigation;
+using QS.Project.Domain;
+using QS.Project.Journal;
+using QS.Services;
+using QS.Utilities;
+using QS.Validation;
+using QS.ViewModels.Dialog;
+using Workwear.Tools;
+using Workwear.Tools.Features;
+using Workwear.Tools.Sizes;
+using Workwear.Domain.Sizes;
+using Workwear.Domain.Stock;
+using Workwear.Domain.Supply;
+using workwear.Journal.ViewModels.Stock;
+
+namespace Workwear.ViewModels.Supply {
+	public class ShipmentViewModel :EntityDialogViewModelBase<Shipment> {
+		public ShipmentViewModel(
+			IEntityUoWBuilder uowBuilder,
+			IUnitOfWorkFactory unitOfWorkFactory,
+			INavigationManager navigation,
+			IInteractiveService interactive,
+			BaseParameters baseParameters,
+			IUserService userService,
+			IValidator validator = null,
+			UnitOfWorkProvider unitOfWorkProvider = null
+		) : base(uowBuilder, unitOfWorkFactory, navigation, validator, unitOfWorkProvider) {
+			
+			this.interactive = interactive ?? throw new ArgumentNullException(nameof(interactive));
+			this.baseParameters = baseParameters ?? throw new ArgumentNullException(nameof(baseParameters));
+			
+			if(Entity.Id == 0)
+				Entity.CreatedbyUser = userService.GetCurrentUser();
+			
+			CalculateTotal();
+		}
+
+		#region Свойства ViewModel
+
+		private readonly IInteractiveService interactive;
+		private readonly BaseParameters baseParameters;
+		private readonly SizeService sizeService = new SizeService();
+		private static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger ();
+		
+		private string total;
+		public string Total {
+			get => total;
+			set => SetField(ref total, value);
+		}
+		
+		private ShipmentItem selectedItem;
+		[PropertyChangedAlso(nameof(CanRemoveItem))]
+		public virtual ShipmentItem SelectedItem {
+			get=>selectedItem;
+			set=>SetField(ref selectedItem, value);
+		}
+
+		#endregion
+
+		#region Проброс свойств документа
+
+		public virtual string DocID {
+			get {
+				return Entity.Id == 0 ? "Новый" : Entity.Id.ToString();
+			}
+		}
+		public virtual string DocTitle => Entity.Title;
+		public virtual UserBase DocCreatedbyUser => Entity.CreatedbyUser;
+		public virtual DateTime DocDate { get => Entity.CreationDate;set => Entity.CreationDate = value;}
+		public virtual DateTime StartPeriod { get => Entity.StartPeriod;set=>Entity.StartPeriod = value; }
+		public virtual DateTime EndPeriod {get=>Entity.EndPeriod;set=>Entity.EndPeriod = value;}
+		public virtual string DocComment {get=>Entity.Comment;set=>Entity.Comment = value;}
+		public virtual IObservableList<ShipmentItem> Items => Entity.Items;
+		
+		#endregion
+
+		#region Свойства View
+
+		public virtual bool CanAddItem => true;
+		public virtual bool CanRemoveItem => SelectedItem != null;
+		
+		public virtual IList<Size> GetSizeVariants(ShipmentItem item) {
+			return sizeService.GetSize(UoW, item.WearSizeType, onlyUseInNomenclature: true).ToList();
+		}
+		
+		public virtual IList<Size> GetHeightVariants(ShipmentItem item) {
+			return sizeService.GetSize(UoW, item.HeightType, onlyUseInNomenclature: true).ToList();
+		}
+
+		#endregion
+
+		#region Методы
+
+		public void AddItem() {
+			var selectJournal = NavigationManager
+				.OpenViewModel<NomenclatureJournalViewModel>( this,OpenPageOptions.AsSlave);
+			selectJournal.ViewModel.Filter.ShowArchival = false;
+			selectJournal.ViewModel.SelectionMode = JournalSelectionMode.Multiple;
+			selectJournal.ViewModel.OnSelectResult += AddItem_OnSelectResult;
+		}
+		
+		private void AddItem_OnSelectResult(object sender, JournalSelectedEventArgs e) {
+			UoW.GetById<Nomenclature>(e.SelectedObjects.Select(x => x.GetId()))
+				.ToList().ForEach(n => Entity.AddItem(n, interactive));
+			CalculateTotal();
+		}
+		
+		public void DeleteItem(ShipmentItem item) {
+			Entity.RemoveItem(item); 
+			OnPropertyChanged(nameof(CanRemoveItem));
+			CalculateTotal();
+		}
+		private void CalculateTotal() {
+			Total = $"Позиций в документе: {Entity.Items.Count}  " +
+			        $"Количество единиц: {Entity.Items.Sum(x => x.Amount)} " +
+			        $"Сумма: {Entity.Items.Sum(x => x.Amount * x.Cost)}{baseParameters.UsedCurrency}";
+		}
+
+		#endregion
+
+		#region Валидация и сохранение
+
+		public override bool Save() {
+			logger.Info ("Запись документа...");
+			
+			logger.Info("Валидация...");
+			if(!Validate()) {
+				logger.Warn("Валидация не пройдена, сохранение отменено.");
+				return false;
+			} else 
+				logger.Info("Валидация пройдена.");
+			
+			logger.Info ("Проверка на дубли");
+			string duplicateMessage = "";
+			foreach(var duplicate in Entity.Items.GroupBy(x => x.StockPosition).Where(x => x.Count() > 1)) {
+				duplicateMessage += $"- {duplicate.First().StockPosition.Title} указано " +
+				                    $"{NumberToTextRus.FormatCase(duplicate.Count(), "{0} раз", "{0} раза", "{0} раз")}" 
+				                    + $", общим количеством {duplicate.Sum(x=>x.Amount)} \n";
+			}
+			if(!String.IsNullOrEmpty(duplicateMessage) && !interactive.Question($"В документе есть повторяющиеся позиции:\n{duplicateMessage}\n Сохранить документ?"))
+				return false;
+
+			if(Entity.Id == 0) 
+				Entity.CreationDate = DateTime.Today;
+			UoWGeneric.Save ();
+			logger.Info ("Документ сохранён.");
+			return true;
+		}
+
+		#endregion
+		
+	}
+}
diff --git a/Workwear/Views/Supply/ShipmentView.cs b/Workwear/Views/Supply/ShipmentView.cs
new file mode 100644
index 000000000..1c90e2b9b
--- /dev/null
+++ b/Workwear/Views/Supply/ShipmentView.cs
@@ -0,0 +1,79 @@
+﻿using System;
+using Gtk;
+using QS.Views.Dialog;
+using Workwear.Domain.Supply;
+using Workwear.ViewModels.Supply;
+
+namespace Workwear.Views.Supply {
+	public partial class ShipmentView : EntityDialogViewBase<ShipmentViewModel,Shipment> {
+		public ShipmentView(ShipmentViewModel viewModel): base(viewModel) {
+			this.Build();
+			ConfigureDlg();
+			ConfigureItems();
+			CommonButtonSubscription();
+		}
+		private void ConfigureDlg() {
+			ylabelNumber.Binding.AddBinding(ViewModel, v=>v.DocID, w=>w.LabelProp)
+				.InitializeFromSource();
+			datePeriod.Binding.AddSource(ViewModel)
+				.AddBinding(v=>v.StartPeriod, w=>w.StartDateOrNull)
+				.AddBinding(v=>v.EndPeriod,w=>w.EndDateOrNull)
+				.InitializeFromSource();
+			ylabelCreatedBy.Binding.AddFuncBinding(ViewModel, v=>v.DocCreatedbyUser!=null? v.DocCreatedbyUser.Name: null, w=>w.LabelProp)
+				.InitializeFromSource();
+			ytextComment.Binding.AddBinding(ViewModel, v=>v.DocComment,w=>w.Buffer.Text)
+				.InitializeFromSource();
+			ylabelAmount.Binding.AddBinding(ViewModel, v=>v.Total, w=>w.LabelProp)
+				.InitializeFromSource();
+			ybuttonAdd.Binding.AddBinding(ViewModel, vm => vm.CanAddItem, w => w.Sensitive).InitializeFromSource();
+			ybuttonDel.Binding.AddBinding(ViewModel, vm => vm.CanRemoveItem, w => w.Sensitive).InitializeFromSource();
+			yenumcomboboxStatus.ItemsEnum=typeof(ShipmentStatus);
+			yenumcomboboxStatus.Binding
+				.AddBinding(Entity,v=>v.Status,w=>w.SelectedItem)
+				.InitializeFromSource();
+		}
+
+		private void ConfigureItems() {
+			ytreeItems.ColumnsConfig = Gamma.GtkWidgets.ColumnsConfigFactory.Create<ShipmentItem>()
+				.AddColumn("Ном. №")
+					.AddReadOnlyTextRenderer(x => x.Nomenclature?.Number)
+				.AddColumn("Наименование").Resizable()
+					.AddTextRenderer(e => e.ItemName).WrapWidth(700)
+					.AddSetter((w, item) => w.Foreground = item.Nomenclature != null ? "black" : "red")
+				.AddColumn("Размер")
+					.AddComboRenderer(x => x.WearSize).SetDisplayFunc(x => x.Name)
+					.DynamicFillListFunc(x => ViewModel.GetSizeVariants(x))
+					.AddSetter((c, n) => c.Editable = n.WearSizeType != null)
+				.AddColumn("Рост").MinWidth(70)
+					.AddComboRenderer(x => x.Height).SetDisplayFunc(x => x.Name)
+					.DynamicFillListFunc(x => ViewModel.GetHeightVariants(x))
+					.AddSetter((c, n) => c.Editable = n.HeightType != null)
+				.AddColumn("Количество")
+					.AddNumericRenderer(e => e.Amount)
+					.Editing(new Adjustment(0, 0, 100000, 1, 10, 1)).WidthChars(8)
+					.AddReadOnlyTextRenderer(e => e.Units?.Name)
+				.AddColumn("Стоимость")
+					.AddNumericRenderer(e => e.Cost)
+					.Editing(new Adjustment(0, 0, 100000000, 100, 1000, 0)).Digits(2).WidthChars(12)
+				.AddColumn("Сумма")
+					.AddNumericRenderer(x => x.Total).Digits(2)
+				.Finish();
+			
+			ytreeItems.Selection.Changed += ytreeItems_Selection_Changed;
+			ytreeItems.ItemsDataSource = ViewModel.Items;
+
+
+		}
+		private void ytreeItems_Selection_Changed(object sender, EventArgs e) {
+			ViewModel.SelectedItem = ytreeItems.GetSelectedObject<ShipmentItem>();
+		}
+		protected void OnYbuttonAddClicked(object sender, EventArgs e) {
+			ViewModel.AddItem();
+		}
+		protected void OnYbuttonDelClicked(object sender, EventArgs e) {
+			ViewModel.DeleteItem(ytreeItems.GetSelectedObject<ShipmentItem>());
+		}
+	}
+}
+
+
diff --git a/Workwear/Workwear.csproj b/Workwear/Workwear.csproj
index 6e13dafb6..a61cc863b 100644
--- a/Workwear/Workwear.csproj
+++ b/Workwear/Workwear.csproj
@@ -138,6 +138,7 @@
     <Compile Include="Journal\ViewModels\Stock\SizeJournalViewModel.cs" />
     <Compile Include="Journal\ViewModels\Stock\SizeTypeJournalViewModel.cs" />
     <Compile Include="Journal\Filter.ViewModels\Company\SubdivisionFilterViewModel.cs" />
+    <Compile Include="Journal\ViewModels\Supply\ShipmentJournalViewModel.cs" />
     <Compile Include="MainWindow.cs" />
     <Compile Include="Models\Stock\OpenStockDocumentsModel.cs" />
     <Compile Include="Models\WearLk\UnansweredClaimsCounter.cs" />
@@ -191,6 +192,7 @@
     <Compile Include="ViewModels\Postomats\PostomatDocumentWithdrawViewModel.cs" />
     <Compile Include="ViewModels\Postomats\PostomatDocumentViewModel.cs" />
     <Compile Include="ViewModels\Regulations\DutyNormViewModel.cs" />
+    <Compile Include="ViewModels\Supply\ShipmentViewModel.cs" />
     <Compile Include="ViewModels\Regulations\NormChildren\NormPostsViewModel.cs" />
     <Compile Include="ViewModels\Sizes\SizeTypeViewModel.cs" />
     <Compile Include="ViewModels\Sizes\SizeViewModel.cs" />
@@ -510,6 +512,8 @@
     <Compile Include="Journal\Filter.ViewModels\Regulations\ProtectionToolsFilterViewModel.cs" />
     <Compile Include="ReportParameters\Views\WearCardsReportView.cs" />
     <Compile Include="gtk-gui\Workwear.ReportParameters.Views.WearCardsReportView.cs" />
+    <Compile Include="Views\Supply\ShipmentView.cs" />
+    <Compile Include="gtk-gui\Workwear.Views.Supply.ShipmentView.cs" />
   </ItemGroup>
   <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
   <ItemGroup>
@@ -747,6 +751,7 @@
     <Folder Include="Views\Export\" />
     <Folder Include="Journal\Filter.Views\Postomats\" />
     <Folder Include="Views\Analytics\" />
+    <Folder Include="Views\Supply\" />
   </ItemGroup>
   <ItemGroup>
     <None Include="Reports\AmountIssuedWearFlat.rdl">
diff --git a/Workwear/gtk-gui/MainWindow.cs b/Workwear/gtk-gui/MainWindow.cs
index 555f5a496..9aa258a87 100644
--- a/Workwear/gtk-gui/MainWindow.cs
+++ b/Workwear/gtk-gui/MainWindow.cs
@@ -215,6 +215,8 @@ public partial class MainWindow
 
 	private global::Gtk.Action ActionWearCardsReport;
 
+	private global::Gtk.Action ActionShipment;
+
 	private global::Gtk.VBox vbox1;
 
 	private global::Gtk.MenuBar menubar1;
@@ -576,6 +578,9 @@ protected virtual void Build()
 		this.ActionWearCardsReport = new global::Gtk.Action("ActionWearCardsReport", global::Mono.Unix.Catalog.GetString("Список сотрудников"), null, null);
 		this.ActionWearCardsReport.ShortLabel = global::Mono.Unix.Catalog.GetString("Список сотрудников");
 		w1.Add(this.ActionWearCardsReport, null);
+		this.ActionShipment = new global::Gtk.Action("ActionShipment", global::Mono.Unix.Catalog.GetString("Планируемые поставки"), null, null);
+		this.ActionShipment.ShortLabel = global::Mono.Unix.Catalog.GetString("Планируемые поставки");
+		w1.Add(this.ActionShipment, null);
 		this.UIManager.InsertActionGroup(w1, 0);
 		this.AddAccelGroup(this.UIManager.AccelGroup);
 		this.Name = "MainWindow";
@@ -611,61 +616,61 @@ protected virtual void Build()
 				"<menuitem name=\'ActionMaxizizeOnStart\' action=\'ActionMaxizizeOnStart\'/></menu><m" +
 				"enu name=\'Action21\' action=\'Action21\'><menuitem name=\'ActionStockDocs\' action=\'A" +
 				"ctionStockDocs\'/><menuitem name=\'ActionStockBalance\' action=\'ActionStockBalance\'" +
-				"/><menuitem name=\'ActionStockMovements\' action=\'ActionStockMovements\'/><menuitem" +
-				" name=\'ActionWarehouseForecasting\' action=\'ActionWarehouseForecasting\'/><separat" +
-				"or/><menuitem name=\'ActionClothingService\' action=\'ActionClothingService\'/><menu" +
-				"item name=\'ActionIssuanceSheets\' action=\'ActionIssuanceSheets\'/></menu><menu nam" +
-				"e=\'ActionServices\' action=\'ActionServices\'><menuitem name=\'ActionMenuNotificatio" +
-				"n\' action=\'ActionMenuNotification\'/><menuitem name=\'ActionMenuClaims\' action=\'Ac" +
-				"tionMenuClaims\'/><menuitem name=\'ActionMenuRatings\' action=\'ActionMenuRatings\'/>" +
-				"<menuitem name=\'ActionSpecCoinsBalance\' action=\'ActionSpecCoinsBalance\'/><separa" +
-				"tor/><menuitem name=\'ActionFullnessPostomats\' action=\'ActionFullnessPostomats\'/>" +
-				"<menuitem name=\'ActionPostomatDocs\' action=\'ActionPostomatDocs\'/><menuitem name=" +
-				"\'ActionPostomatDocsWithdraw\' action=\'ActionPostomatDocsWithdraw\'/></menu><menu n" +
-				"ame=\'Action47\' action=\'Action47\'><menuitem name=\'ActionOrganizations\' action=\'Ac" +
-				"tionOrganizations\'/><menuitem name=\'ActionObjects\' action=\'ActionObjects\'/><menu" +
-				"item name=\'ActionDepartment\' action=\'ActionDepartment\'/><menuitem name=\'ActionEm" +
-				"ployeeGroup\' action=\'ActionEmployeeGroup\'/><menuitem name=\'ActionEmployees\' acti" +
-				"on=\'ActionEmployees\'/><separator/><menuitem name=\'ActionRegulationDoc\' action=\'A" +
-				"ctionRegulationDoc\'/><menuitem name=\'ActionProtectionTools\' action=\'ActionProtec" +
-				"tionTools\'/><menuitem name=\'ActionNorms\' action=\'ActionNorms\'/><menuitem name=\'A" +
-				"ctionConditionNorm\' action=\'ActionConditionNorm\'/><menuitem name=\'ActionDutyNorm" +
-				"\' action=\'ActionDutyNorm\'/><menuitem name=\'Action45\' action=\'Action45\'/><separat" +
-				"or/><menuitem name=\'Action43\' action=\'Action43\'/><menuitem name=\'Action42\' actio" +
-				"n=\'Action42\'/><menuitem name=\'Action6\' action=\'Action6\'/><menuitem name=\'ActionW" +
-				"arehouse\' action=\'ActionWarehouse\'/><menuitem name=\'ActionOwner\' action=\'ActionO" +
-				"wner\'/><menuitem name=\'ActionBarcodes\' action=\'ActionBarcodes\'/><separator/><men" +
-				"uitem name=\'ActionSizeType\' action=\'ActionSizeType\'/><menuitem name=\'ActionSize\'" +
-				" action=\'ActionSize\'/><separator/><menuitem name=\'Action7\' action=\'Action7\'/><me" +
-				"nuitem name=\'ActionNotificationTemplates\' action=\'ActionNotificationTemplates\'/>" +
-				"<separator/><menuitem name=\'ActionProfession\' action=\'ActionProfession\'/><menuit" +
-				"em name=\'Action8\' action=\'Action8\'/><menuitem name=\'ActionVacationTypes\' action=" +
-				"\'ActionVacationTypes\'/><menuitem name=\'ActionCostCenter\' action=\'ActionCostCente" +
-				"r\'/><menuitem name=\'ActionLeaders\' action=\'ActionLeaders\'/></menu><menu name=\'Ac" +
-				"tionReports\' action=\'ActionReports\'><menuitem name=\'Action11\' action=\'Action11\'/" +
-				"><menuitem name=\'ActionStockOperations\' action=\'ActionStockOperations\'/><separat" +
-				"or/><menuitem name=\'Action10\' action=\'Action10\'/><menuitem name=\'Action12\' actio" +
-				"n=\'Action12\'/><separator/><menuitem name=\'ActionAmountIssuedWear\' action=\'Action" +
-				"AmountIssuedWear\'/><menuitem name=\'ActionWriteOffAct\' action=\'ActionWriteOffAct\'" +
-				"/><menuitem name=\'ActionClothingServiceReport\' action=\'ActionClothingServiceRepo" +
-				"rt\'/><separator/><menuitem name=\'ActionRequestSheet\' action=\'ActionRequestSheet\'" +
-				"/><menuitem name=\'ActionAverageAnnualNeed\' action=\'ActionAverageAnnualNeed\'/><me" +
-				"nu name=\'Action\' action=\'Action\'><menuitem name=\'ActionNotIssuedSheetDetail\' act" +
-				"ion=\'ActionNotIssuedSheetDetail\'/><menuitem name=\'ActionNotIssuedSheetSummary\' a" +
-				"ction=\'ActionNotIssuedSheetSummary\'/></menu><separator/><menuitem name=\'ActionWe" +
-				"arCardsReport\' action=\'ActionWearCardsReport\'/><menuitem name=\'ActionAmountEmplo" +
-				"yeeGetWear\' action=\'ActionAmountEmployeeGetWear\'/><menuitem name=\'ActionProvisio" +
-				"n\' action=\'ActionProvision\'/><menuitem name=\'ActionBarcodeCompletenessReport\' ac" +
-				"tion=\'ActionBarcodeCompletenessReport\'/></menu><menu name=\'ActionHelp\' action=\'A" +
-				"ctionHelp\'><menuitem name=\'helpAction\' action=\'helpAction\'/><menuitem name=\'Acti" +
-				"onAdminGuide\' action=\'ActionAdminGuide\'/><separator/><menuitem name=\'ActionHisto" +
-				"ry\' action=\'ActionHistory\'/><menu name=\'ActionUpdateChannel\' action=\'ActionUpdat" +
-				"eChannel\'><menuitem name=\'ActionChannelCurrent\' action=\'ActionChannelCurrent\'/><" +
-				"menuitem name=\'ActionChannelStable\' action=\'ActionChannelStable\'/></menu><menuit" +
-				"em name=\'ActionUpdate\' action=\'ActionUpdate\'/><separator/><menuitem name=\'Action" +
-				"Site\' action=\'ActionSite\'/><separator/><menuitem name=\'ActionSN\' action=\'ActionS" +
-				"N\'/><separator/><menuitem name=\'aboutAction\' action=\'aboutAction\'/></menu></menu" +
-				"bar></ui>");
+				"/><menuitem name=\'ActionStockMovements\' action=\'ActionStockMovements\'/><separato" +
+				"r/><menuitem name=\'ActionWarehouseForecasting\' action=\'ActionWarehouseForecastin" +
+				"g\'/><menuitem name=\'ActionShipment\' action=\'ActionShipment\'/><separator/><menuit" +
+				"em name=\'ActionClothingService\' action=\'ActionClothingService\'/><menuitem name=\'" +
+				"ActionIssuanceSheets\' action=\'ActionIssuanceSheets\'/></menu><menu name=\'ActionSe" +
+				"rvices\' action=\'ActionServices\'><menuitem name=\'ActionMenuNotification\' action=\'" +
+				"ActionMenuNotification\'/><menuitem name=\'ActionMenuClaims\' action=\'ActionMenuCla" +
+				"ims\'/><menuitem name=\'ActionMenuRatings\' action=\'ActionMenuRatings\'/><menuitem n" +
+				"ame=\'ActionSpecCoinsBalance\' action=\'ActionSpecCoinsBalance\'/><separator/><menui" +
+				"tem name=\'ActionFullnessPostomats\' action=\'ActionFullnessPostomats\'/><menuitem n" +
+				"ame=\'ActionPostomatDocs\' action=\'ActionPostomatDocs\'/><menuitem name=\'ActionPost" +
+				"omatDocsWithdraw\' action=\'ActionPostomatDocsWithdraw\'/></menu><menu name=\'Action" +
+				"47\' action=\'Action47\'><menuitem name=\'ActionOrganizations\' action=\'ActionOrganiz" +
+				"ations\'/><menuitem name=\'ActionObjects\' action=\'ActionObjects\'/><menuitem name=\'" +
+				"ActionDepartment\' action=\'ActionDepartment\'/><menuitem name=\'ActionEmployeeGroup" +
+				"\' action=\'ActionEmployeeGroup\'/><menuitem name=\'ActionEmployees\' action=\'ActionE" +
+				"mployees\'/><separator/><menuitem name=\'ActionRegulationDoc\' action=\'ActionRegula" +
+				"tionDoc\'/><menuitem name=\'ActionProtectionTools\' action=\'ActionProtectionTools\'/" +
+				"><menuitem name=\'ActionNorms\' action=\'ActionNorms\'/><menuitem name=\'ActionCondit" +
+				"ionNorm\' action=\'ActionConditionNorm\'/><menuitem name=\'ActionDutyNorm\' action=\'A" +
+				"ctionDutyNorm\'/><menuitem name=\'Action45\' action=\'Action45\'/><separator/><menuit" +
+				"em name=\'Action43\' action=\'Action43\'/><menuitem name=\'Action42\' action=\'Action42" +
+				"\'/><menuitem name=\'Action6\' action=\'Action6\'/><menuitem name=\'ActionWarehouse\' a" +
+				"ction=\'ActionWarehouse\'/><menuitem name=\'ActionOwner\' action=\'ActionOwner\'/><men" +
+				"uitem name=\'ActionBarcodes\' action=\'ActionBarcodes\'/><separator/><menuitem name=" +
+				"\'ActionSizeType\' action=\'ActionSizeType\'/><menuitem name=\'ActionSize\' action=\'Ac" +
+				"tionSize\'/><separator/><menuitem name=\'Action7\' action=\'Action7\'/><menuitem name" +
+				"=\'ActionNotificationTemplates\' action=\'ActionNotificationTemplates\'/><separator/" +
+				"><menuitem name=\'ActionProfession\' action=\'ActionProfession\'/><menuitem name=\'Ac" +
+				"tion8\' action=\'Action8\'/><menuitem name=\'ActionVacationTypes\' action=\'ActionVaca" +
+				"tionTypes\'/><menuitem name=\'ActionCostCenter\' action=\'ActionCostCenter\'/><menuit" +
+				"em name=\'ActionLeaders\' action=\'ActionLeaders\'/></menu><menu name=\'ActionReports" +
+				"\' action=\'ActionReports\'><menuitem name=\'Action11\' action=\'Action11\'/><menuitem " +
+				"name=\'ActionStockOperations\' action=\'ActionStockOperations\'/><separator/><menuit" +
+				"em name=\'Action10\' action=\'Action10\'/><menuitem name=\'Action12\' action=\'Action12" +
+				"\'/><separator/><menuitem name=\'ActionAmountIssuedWear\' action=\'ActionAmountIssue" +
+				"dWear\'/><menuitem name=\'ActionWriteOffAct\' action=\'ActionWriteOffAct\'/><menuitem" +
+				" name=\'ActionClothingServiceReport\' action=\'ActionClothingServiceReport\'/><separ" +
+				"ator/><menuitem name=\'ActionRequestSheet\' action=\'ActionRequestSheet\'/><menuitem" +
+				" name=\'ActionAverageAnnualNeed\' action=\'ActionAverageAnnualNeed\'/><menu name=\'Ac" +
+				"tion\' action=\'Action\'><menuitem name=\'ActionNotIssuedSheetDetail\' action=\'Action" +
+				"NotIssuedSheetDetail\'/><menuitem name=\'ActionNotIssuedSheetSummary\' action=\'Acti" +
+				"onNotIssuedSheetSummary\'/></menu><separator/><menuitem name=\'ActionWearCardsRepo" +
+				"rt\' action=\'ActionWearCardsReport\'/><menuitem name=\'ActionAmountEmployeeGetWear\'" +
+				" action=\'ActionAmountEmployeeGetWear\'/><menuitem name=\'ActionProvision\' action=\'" +
+				"ActionProvision\'/><menuitem name=\'ActionBarcodeCompletenessReport\' action=\'Actio" +
+				"nBarcodeCompletenessReport\'/></menu><menu name=\'ActionHelp\' action=\'ActionHelp\'>" +
+				"<menuitem name=\'helpAction\' action=\'helpAction\'/><menuitem name=\'ActionAdminGuid" +
+				"e\' action=\'ActionAdminGuide\'/><separator/><menuitem name=\'ActionHistory\' action=" +
+				"\'ActionHistory\'/><menu name=\'ActionUpdateChannel\' action=\'ActionUpdateChannel\'><" +
+				"menuitem name=\'ActionChannelCurrent\' action=\'ActionChannelCurrent\'/><menuitem na" +
+				"me=\'ActionChannelStable\' action=\'ActionChannelStable\'/></menu><menuitem name=\'Ac" +
+				"tionUpdate\' action=\'ActionUpdate\'/><separator/><menuitem name=\'ActionSite\' actio" +
+				"n=\'ActionSite\'/><separator/><menuitem name=\'ActionSN\' action=\'ActionSN\'/><separa" +
+				"tor/><menuitem name=\'aboutAction\' action=\'aboutAction\'/></menu></menubar></ui>");
 		this.menubar1 = ((global::Gtk.MenuBar)(this.UIManager.GetWidget("/menubar1")));
 		this.menubar1.Name = "menubar1";
 		this.vbox1.Add(this.menubar1);
@@ -885,5 +890,6 @@ protected virtual void Build()
 		this.ActionWriteOffAct.Activated += new global::System.EventHandler(this.OnActionWriteOffActActivated);
 		this.ActionStockOperations.Activated += new global::System.EventHandler(this.OnActionWarehouseTransferReportActivated);
 		this.ActionWearCardsReport.Activated += new global::System.EventHandler(this.OnActionWearCardsReportActivated);
+		this.ActionShipment.Activated += new global::System.EventHandler(this.OnActionShipmentActivated);
 	}
 }
diff --git a/Workwear/gtk-gui/Workwear.Views.Supply.ShipmentView.cs b/Workwear/gtk-gui/Workwear.Views.Supply.ShipmentView.cs
new file mode 100644
index 000000000..9c4776b6a
--- /dev/null
+++ b/Workwear/gtk-gui/Workwear.Views.Supply.ShipmentView.cs
@@ -0,0 +1,384 @@
+
+// This file has been generated by the GUI designer. Do not modify.
+namespace Workwear.Views.Supply
+{
+	public partial class ShipmentView
+	{
+		private global::Gamma.GtkWidgets.yVBox yvbox1;
+
+		private global::Gamma.GtkWidgets.yHBox yhbox1;
+
+		private global::Gamma.GtkWidgets.yButton buttonSave;
+
+		private global::Gamma.GtkWidgets.yButton buttonCancel;
+
+		private global::Gamma.GtkWidgets.yHBox yhbox2;
+
+		private global::Gamma.GtkWidgets.yTable ytable1;
+
+		private global::Gtk.ScrolledWindow scrolledwindow;
+
+		private global::Gamma.GtkWidgets.yTextView ytextComment;
+
+		private global::Gamma.GtkWidgets.yHBox yhbox3;
+
+		private global::Gamma.GtkWidgets.yLabel ylabelNumber;
+
+		private global::Gamma.GtkWidgets.yHBox yhbox6;
+
+		private global::QS.Widgets.GtkUI.DateRangePicker datePeriod;
+
+		private global::Gamma.GtkWidgets.yLabel ylabel1;
+
+		private global::Gamma.GtkWidgets.yLabel ylabel10;
+
+		private global::Gamma.GtkWidgets.yLabel ylabel3;
+
+		private global::Gamma.GtkWidgets.yLabel ylabel8;
+
+		private global::Gamma.GtkWidgets.yLabel ylabelCreatedBy;
+
+		private global::Gamma.GtkWidgets.yLabel ylabelStatus;
+
+		private global::Gamma.GtkWidgets.yTable ytable2;
+
+		private global::Gamma.Widgets.yEnumComboBox yenumcomboboxStatus;
+
+		private global::Gamma.GtkWidgets.yVBox yvbox3;
+
+		private global::Gamma.GtkWidgets.yHBox yhbox4;
+
+		private global::Gamma.GtkWidgets.yLabel ylabel6;
+
+		private global::Gtk.ScrolledWindow scrolledwindow2;
+
+		private global::Gamma.GtkWidgets.yTreeView ytreeItems;
+
+		private global::Gamma.GtkWidgets.yHBox yhbox5;
+
+		private global::Gamma.GtkWidgets.yButton ybuttonAdd;
+
+		private global::Gamma.GtkWidgets.yButton ybuttonDel;
+
+		private global::Gamma.GtkWidgets.yLabel ylabelAmount;
+
+		protected virtual void Build()
+		{
+			global::Stetic.Gui.Initialize(this);
+			// Widget Workwear.Views.Supply.ShipmentView
+			global::Stetic.BinContainer.Attach(this);
+			this.Name = "Workwear.Views.Supply.ShipmentView";
+			// Container child Workwear.Views.Supply.ShipmentView.Gtk.Container+ContainerChild
+			this.yvbox1 = new global::Gamma.GtkWidgets.yVBox();
+			this.yvbox1.WidthRequest = 0;
+			this.yvbox1.HeightRequest = 0;
+			this.yvbox1.Name = "yvbox1";
+			this.yvbox1.BorderWidth = ((uint)(2));
+			// Container child yvbox1.Gtk.Box+BoxChild
+			this.yhbox1 = new global::Gamma.GtkWidgets.yHBox();
+			this.yhbox1.Name = "yhbox1";
+			this.yhbox1.Spacing = 6;
+			// Container child yhbox1.Gtk.Box+BoxChild
+			this.buttonSave = new global::Gamma.GtkWidgets.yButton();
+			this.buttonSave.CanFocus = true;
+			this.buttonSave.Name = "buttonSave";
+			this.buttonSave.UseUnderline = true;
+			this.buttonSave.Label = global::Mono.Unix.Catalog.GetString("Сохранить");
+			global::Gtk.Image w1 = new global::Gtk.Image();
+			w1.Pixbuf = global::Stetic.IconLoader.LoadIcon(this, "gtk-save", global::Gtk.IconSize.Menu);
+			this.buttonSave.Image = w1;
+			this.yhbox1.Add(this.buttonSave);
+			global::Gtk.Box.BoxChild w2 = ((global::Gtk.Box.BoxChild)(this.yhbox1[this.buttonSave]));
+			w2.Position = 0;
+			w2.Expand = false;
+			w2.Fill = false;
+			// Container child yhbox1.Gtk.Box+BoxChild
+			this.buttonCancel = new global::Gamma.GtkWidgets.yButton();
+			this.buttonCancel.CanFocus = true;
+			this.buttonCancel.Name = "buttonCancel";
+			this.buttonCancel.UseUnderline = true;
+			this.buttonCancel.Label = global::Mono.Unix.Catalog.GetString("Отменить");
+			global::Gtk.Image w3 = new global::Gtk.Image();
+			w3.Pixbuf = global::Stetic.IconLoader.LoadIcon(this, "gtk-revert-to-saved", global::Gtk.IconSize.Menu);
+			this.buttonCancel.Image = w3;
+			this.yhbox1.Add(this.buttonCancel);
+			global::Gtk.Box.BoxChild w4 = ((global::Gtk.Box.BoxChild)(this.yhbox1[this.buttonCancel]));
+			w4.Position = 1;
+			w4.Expand = false;
+			w4.Fill = false;
+			this.yvbox1.Add(this.yhbox1);
+			global::Gtk.Box.BoxChild w5 = ((global::Gtk.Box.BoxChild)(this.yvbox1[this.yhbox1]));
+			w5.Position = 0;
+			w5.Expand = false;
+			w5.Fill = false;
+			// Container child yvbox1.Gtk.Box+BoxChild
+			this.yhbox2 = new global::Gamma.GtkWidgets.yHBox();
+			this.yhbox2.Name = "yhbox2";
+			this.yhbox2.Spacing = 6;
+			this.yhbox2.BorderWidth = ((uint)(3));
+			// Container child yhbox2.Gtk.Box+BoxChild
+			this.ytable1 = new global::Gamma.GtkWidgets.yTable();
+			this.ytable1.Name = "ytable1";
+			this.ytable1.NRows = ((uint)(5));
+			this.ytable1.NColumns = ((uint)(3));
+			this.ytable1.RowSpacing = ((uint)(6));
+			this.ytable1.ColumnSpacing = ((uint)(6));
+			// Container child ytable1.Gtk.Table+TableChild
+			this.scrolledwindow = new global::Gtk.ScrolledWindow();
+			this.scrolledwindow.Name = "scrolledwindow";
+			this.scrolledwindow.ShadowType = ((global::Gtk.ShadowType)(1));
+			// Container child scrolledwindow.Gtk.Container+ContainerChild
+			this.ytextComment = new global::Gamma.GtkWidgets.yTextView();
+			this.ytextComment.CanFocus = true;
+			this.ytextComment.Name = "ytextComment";
+			this.ytextComment.AcceptsTab = false;
+			this.ytextComment.WrapMode = ((global::Gtk.WrapMode)(3));
+			this.scrolledwindow.Add(this.ytextComment);
+			this.ytable1.Add(this.scrolledwindow);
+			global::Gtk.Table.TableChild w7 = ((global::Gtk.Table.TableChild)(this.ytable1[this.scrolledwindow]));
+			w7.TopAttach = ((uint)(4));
+			w7.BottomAttach = ((uint)(5));
+			w7.LeftAttach = ((uint)(1));
+			w7.RightAttach = ((uint)(2));
+			// Container child ytable1.Gtk.Table+TableChild
+			this.yhbox3 = new global::Gamma.GtkWidgets.yHBox();
+			this.yhbox3.Name = "yhbox3";
+			this.yhbox3.Spacing = 6;
+			// Container child yhbox3.Gtk.Box+BoxChild
+			this.ylabelNumber = new global::Gamma.GtkWidgets.yLabel();
+			this.ylabelNumber.Name = "ylabelNumber";
+			this.ylabelNumber.Xalign = 0F;
+			this.ylabelNumber.LabelProp = global::Mono.Unix.Catalog.GetString("ylabel1");
+			this.yhbox3.Add(this.ylabelNumber);
+			global::Gtk.Box.BoxChild w8 = ((global::Gtk.Box.BoxChild)(this.yhbox3[this.ylabelNumber]));
+			w8.Position = 0;
+			w8.Expand = false;
+			w8.Fill = false;
+			this.ytable1.Add(this.yhbox3);
+			global::Gtk.Table.TableChild w9 = ((global::Gtk.Table.TableChild)(this.ytable1[this.yhbox3]));
+			w9.LeftAttach = ((uint)(1));
+			w9.RightAttach = ((uint)(2));
+			w9.XOptions = ((global::Gtk.AttachOptions)(4));
+			w9.YOptions = ((global::Gtk.AttachOptions)(4));
+			// Container child ytable1.Gtk.Table+TableChild
+			this.yhbox6 = new global::Gamma.GtkWidgets.yHBox();
+			this.yhbox6.Name = "yhbox6";
+			this.yhbox6.Spacing = 6;
+			// Container child yhbox6.Gtk.Box+BoxChild
+			this.datePeriod = new global::QS.Widgets.GtkUI.DateRangePicker();
+			this.datePeriod.Events = ((global::Gdk.EventMask)(256));
+			this.datePeriod.Name = "datePeriod";
+			this.datePeriod.StartDate = new global::System.DateTime(0);
+			this.datePeriod.EndDate = new global::System.DateTime(0);
+			this.yhbox6.Add(this.datePeriod);
+			global::Gtk.Box.BoxChild w10 = ((global::Gtk.Box.BoxChild)(this.yhbox6[this.datePeriod]));
+			w10.Position = 0;
+			w10.Expand = false;
+			this.ytable1.Add(this.yhbox6);
+			global::Gtk.Table.TableChild w11 = ((global::Gtk.Table.TableChild)(this.ytable1[this.yhbox6]));
+			w11.TopAttach = ((uint)(2));
+			w11.BottomAttach = ((uint)(3));
+			w11.LeftAttach = ((uint)(1));
+			w11.RightAttach = ((uint)(2));
+			w11.XOptions = ((global::Gtk.AttachOptions)(4));
+			w11.YOptions = ((global::Gtk.AttachOptions)(4));
+			// Container child ytable1.Gtk.Table+TableChild
+			this.ylabel1 = new global::Gamma.GtkWidgets.yLabel();
+			this.ylabel1.Name = "ylabel1";
+			this.ylabel1.Xalign = 1F;
+			this.ylabel1.LabelProp = global::Mono.Unix.Catalog.GetString("Номер:");
+			this.ytable1.Add(this.ylabel1);
+			global::Gtk.Table.TableChild w12 = ((global::Gtk.Table.TableChild)(this.ytable1[this.ylabel1]));
+			w12.XOptions = ((global::Gtk.AttachOptions)(4));
+			w12.YOptions = ((global::Gtk.AttachOptions)(4));
+			// Container child ytable1.Gtk.Table+TableChild
+			this.ylabel10 = new global::Gamma.GtkWidgets.yLabel();
+			this.ylabel10.Name = "ylabel10";
+			this.ylabel10.Xalign = 1F;
+			this.ylabel10.LabelProp = global::Mono.Unix.Catalog.GetString("Период<span foreground=\"red\">*</span>:");
+			this.ylabel10.UseMarkup = true;
+			this.ytable1.Add(this.ylabel10);
+			global::Gtk.Table.TableChild w13 = ((global::Gtk.Table.TableChild)(this.ytable1[this.ylabel10]));
+			w13.TopAttach = ((uint)(2));
+			w13.BottomAttach = ((uint)(3));
+			w13.XOptions = ((global::Gtk.AttachOptions)(4));
+			w13.YOptions = ((global::Gtk.AttachOptions)(4));
+			// Container child ytable1.Gtk.Table+TableChild
+			this.ylabel3 = new global::Gamma.GtkWidgets.yLabel();
+			this.ylabel3.Name = "ylabel3";
+			this.ylabel3.Xalign = 1F;
+			this.ylabel3.LabelProp = global::Mono.Unix.Catalog.GetString("Пользователь:");
+			this.ytable1.Add(this.ylabel3);
+			global::Gtk.Table.TableChild w14 = ((global::Gtk.Table.TableChild)(this.ytable1[this.ylabel3]));
+			w14.TopAttach = ((uint)(1));
+			w14.BottomAttach = ((uint)(2));
+			w14.XOptions = ((global::Gtk.AttachOptions)(4));
+			w14.YOptions = ((global::Gtk.AttachOptions)(4));
+			// Container child ytable1.Gtk.Table+TableChild
+			this.ylabel8 = new global::Gamma.GtkWidgets.yLabel();
+			this.ylabel8.Name = "ylabel8";
+			this.ylabel8.Xalign = 1F;
+			this.ylabel8.Yalign = 0F;
+			this.ylabel8.LabelProp = global::Mono.Unix.Catalog.GetString("Комментарий:");
+			this.ytable1.Add(this.ylabel8);
+			global::Gtk.Table.TableChild w15 = ((global::Gtk.Table.TableChild)(this.ytable1[this.ylabel8]));
+			w15.TopAttach = ((uint)(4));
+			w15.BottomAttach = ((uint)(5));
+			w15.XOptions = ((global::Gtk.AttachOptions)(4));
+			w15.YOptions = ((global::Gtk.AttachOptions)(4));
+			// Container child ytable1.Gtk.Table+TableChild
+			this.ylabelCreatedBy = new global::Gamma.GtkWidgets.yLabel();
+			this.ylabelCreatedBy.Name = "ylabelCreatedBy";
+			this.ylabelCreatedBy.Xalign = 0F;
+			this.ylabelCreatedBy.LabelProp = global::Mono.Unix.Catalog.GetString("ylabel7");
+			this.ytable1.Add(this.ylabelCreatedBy);
+			global::Gtk.Table.TableChild w16 = ((global::Gtk.Table.TableChild)(this.ytable1[this.ylabelCreatedBy]));
+			w16.TopAttach = ((uint)(1));
+			w16.BottomAttach = ((uint)(2));
+			w16.LeftAttach = ((uint)(1));
+			w16.RightAttach = ((uint)(2));
+			w16.XOptions = ((global::Gtk.AttachOptions)(4));
+			w16.YOptions = ((global::Gtk.AttachOptions)(4));
+			// Container child ytable1.Gtk.Table+TableChild
+			this.ylabelStatus = new global::Gamma.GtkWidgets.yLabel();
+			this.ylabelStatus.Name = "ylabelStatus";
+			this.ylabelStatus.Xalign = 1F;
+			this.ylabelStatus.LabelProp = global::Mono.Unix.Catalog.GetString("Статус поставки:");
+			this.ytable1.Add(this.ylabelStatus);
+			global::Gtk.Table.TableChild w17 = ((global::Gtk.Table.TableChild)(this.ytable1[this.ylabelStatus]));
+			w17.TopAttach = ((uint)(3));
+			w17.BottomAttach = ((uint)(4));
+			w17.XOptions = ((global::Gtk.AttachOptions)(4));
+			w17.YOptions = ((global::Gtk.AttachOptions)(4));
+			// Container child ytable1.Gtk.Table+TableChild
+			this.ytable2 = new global::Gamma.GtkWidgets.yTable();
+			this.ytable2.Name = "ytable2";
+			this.ytable2.NColumns = ((uint)(2));
+			this.ytable2.Homogeneous = true;
+			this.ytable2.RowSpacing = ((uint)(6));
+			this.ytable2.ColumnSpacing = ((uint)(6));
+			// Container child ytable2.Gtk.Table+TableChild
+			this.yenumcomboboxStatus = new global::Gamma.Widgets.yEnumComboBox();
+			this.yenumcomboboxStatus.Name = "yenumcomboboxStatus";
+			this.yenumcomboboxStatus.ShowSpecialStateAll = false;
+			this.yenumcomboboxStatus.ShowSpecialStateNot = false;
+			this.yenumcomboboxStatus.UseShortTitle = false;
+			this.yenumcomboboxStatus.DefaultFirst = true;
+			this.ytable2.Add(this.yenumcomboboxStatus);
+			global::Gtk.Table.TableChild w18 = ((global::Gtk.Table.TableChild)(this.ytable2[this.yenumcomboboxStatus]));
+			w18.XOptions = ((global::Gtk.AttachOptions)(4));
+			w18.YOptions = ((global::Gtk.AttachOptions)(4));
+			this.ytable1.Add(this.ytable2);
+			global::Gtk.Table.TableChild w19 = ((global::Gtk.Table.TableChild)(this.ytable1[this.ytable2]));
+			w19.TopAttach = ((uint)(3));
+			w19.BottomAttach = ((uint)(4));
+			w19.LeftAttach = ((uint)(1));
+			w19.RightAttach = ((uint)(2));
+			w19.XOptions = ((global::Gtk.AttachOptions)(4));
+			w19.YOptions = ((global::Gtk.AttachOptions)(4));
+			this.yhbox2.Add(this.ytable1);
+			global::Gtk.Box.BoxChild w20 = ((global::Gtk.Box.BoxChild)(this.yhbox2[this.ytable1]));
+			w20.Position = 0;
+			this.yvbox1.Add(this.yhbox2);
+			global::Gtk.Box.BoxChild w21 = ((global::Gtk.Box.BoxChild)(this.yvbox1[this.yhbox2]));
+			w21.Position = 1;
+			w21.Expand = false;
+			w21.Fill = false;
+			// Container child yvbox1.Gtk.Box+BoxChild
+			this.yvbox3 = new global::Gamma.GtkWidgets.yVBox();
+			this.yvbox3.Name = "yvbox3";
+			this.yvbox3.Spacing = 6;
+			// Container child yvbox3.Gtk.Box+BoxChild
+			this.yhbox4 = new global::Gamma.GtkWidgets.yHBox();
+			this.yhbox4.Name = "yhbox4";
+			this.yhbox4.Spacing = 6;
+			// Container child yhbox4.Gtk.Box+BoxChild
+			this.ylabel6 = new global::Gamma.GtkWidgets.yLabel();
+			this.ylabel6.Name = "ylabel6";
+			this.ylabel6.LabelProp = global::Mono.Unix.Catalog.GetString("Поставка:");
+			this.yhbox4.Add(this.ylabel6);
+			global::Gtk.Box.BoxChild w22 = ((global::Gtk.Box.BoxChild)(this.yhbox4[this.ylabel6]));
+			w22.Position = 0;
+			w22.Expand = false;
+			w22.Fill = false;
+			this.yvbox3.Add(this.yhbox4);
+			global::Gtk.Box.BoxChild w23 = ((global::Gtk.Box.BoxChild)(this.yvbox3[this.yhbox4]));
+			w23.Position = 0;
+			w23.Expand = false;
+			w23.Fill = false;
+			// Container child yvbox3.Gtk.Box+BoxChild
+			this.scrolledwindow2 = new global::Gtk.ScrolledWindow();
+			this.scrolledwindow2.CanFocus = true;
+			this.scrolledwindow2.Name = "scrolledwindow2";
+			this.scrolledwindow2.ShadowType = ((global::Gtk.ShadowType)(1));
+			// Container child scrolledwindow2.Gtk.Container+ContainerChild
+			this.ytreeItems = new global::Gamma.GtkWidgets.yTreeView();
+			this.ytreeItems.CanFocus = true;
+			this.ytreeItems.Name = "ytreeItems";
+			this.scrolledwindow2.Add(this.ytreeItems);
+			this.yvbox3.Add(this.scrolledwindow2);
+			global::Gtk.Box.BoxChild w25 = ((global::Gtk.Box.BoxChild)(this.yvbox3[this.scrolledwindow2]));
+			w25.Position = 1;
+			// Container child yvbox3.Gtk.Box+BoxChild
+			this.yhbox5 = new global::Gamma.GtkWidgets.yHBox();
+			this.yhbox5.Name = "yhbox5";
+			this.yhbox5.Spacing = 6;
+			// Container child yhbox5.Gtk.Box+BoxChild
+			this.ybuttonAdd = new global::Gamma.GtkWidgets.yButton();
+			this.ybuttonAdd.CanFocus = true;
+			this.ybuttonAdd.Name = "ybuttonAdd";
+			this.ybuttonAdd.UseUnderline = true;
+			this.ybuttonAdd.Label = global::Mono.Unix.Catalog.GetString("Добавить");
+			global::Gtk.Image w26 = new global::Gtk.Image();
+			w26.Pixbuf = global::Stetic.IconLoader.LoadIcon(this, "gtk-add", global::Gtk.IconSize.Menu);
+			this.ybuttonAdd.Image = w26;
+			this.yhbox5.Add(this.ybuttonAdd);
+			global::Gtk.Box.BoxChild w27 = ((global::Gtk.Box.BoxChild)(this.yhbox5[this.ybuttonAdd]));
+			w27.Position = 0;
+			w27.Expand = false;
+			w27.Fill = false;
+			// Container child yhbox5.Gtk.Box+BoxChild
+			this.ybuttonDel = new global::Gamma.GtkWidgets.yButton();
+			this.ybuttonDel.Sensitive = false;
+			this.ybuttonDel.CanFocus = true;
+			this.ybuttonDel.Name = "ybuttonDel";
+			this.ybuttonDel.UseUnderline = true;
+			this.ybuttonDel.Label = global::Mono.Unix.Catalog.GetString("Удалить");
+			global::Gtk.Image w28 = new global::Gtk.Image();
+			w28.Pixbuf = global::Stetic.IconLoader.LoadIcon(this, "gtk-remove", global::Gtk.IconSize.Menu);
+			this.ybuttonDel.Image = w28;
+			this.yhbox5.Add(this.ybuttonDel);
+			global::Gtk.Box.BoxChild w29 = ((global::Gtk.Box.BoxChild)(this.yhbox5[this.ybuttonDel]));
+			w29.Position = 1;
+			w29.Expand = false;
+			w29.Fill = false;
+			// Container child yhbox5.Gtk.Box+BoxChild
+			this.ylabelAmount = new global::Gamma.GtkWidgets.yLabel();
+			this.ylabelAmount.Name = "ylabelAmount";
+			this.ylabelAmount.LabelProp = global::Mono.Unix.Catalog.GetString("Количество:");
+			this.ylabelAmount.Justify = ((global::Gtk.Justification)(1));
+			this.yhbox5.Add(this.ylabelAmount);
+			global::Gtk.Box.BoxChild w30 = ((global::Gtk.Box.BoxChild)(this.yhbox5[this.ylabelAmount]));
+			w30.PackType = ((global::Gtk.PackType)(1));
+			w30.Position = 2;
+			w30.Expand = false;
+			w30.Fill = false;
+			this.yvbox3.Add(this.yhbox5);
+			global::Gtk.Box.BoxChild w31 = ((global::Gtk.Box.BoxChild)(this.yvbox3[this.yhbox5]));
+			w31.Position = 2;
+			w31.Expand = false;
+			w31.Fill = false;
+			this.yvbox1.Add(this.yvbox3);
+			global::Gtk.Box.BoxChild w32 = ((global::Gtk.Box.BoxChild)(this.yvbox1[this.yvbox3]));
+			w32.Position = 2;
+			this.Add(this.yvbox1);
+			if ((this.Child != null))
+			{
+				this.Child.ShowAll();
+			}
+			this.Hide();
+			this.ybuttonAdd.Clicked += new global::System.EventHandler(this.OnYbuttonAddClicked);
+			this.ybuttonDel.Clicked += new global::System.EventHandler(this.OnYbuttonDelClicked);
+		}
+	}
+}
diff --git a/Workwear/gtk-gui/gui.stetic b/Workwear/gtk-gui/gui.stetic
index 7582d4381..d99d7642c 100644
--- a/Workwear/gtk-gui/gui.stetic
+++ b/Workwear/gtk-gui/gui.stetic
@@ -5218,6 +5218,12 @@
         <property name="ShortLabel" translatable="yes">Список сотрудников</property>
         <signal name="Activated" handler="OnActionWearCardsReportActivated" />
       </action>
+      <action id="ActionShipment">
+        <property name="Type">Action</property>
+        <property name="Label" translatable="yes">Планируемые поставки</property>
+        <property name="ShortLabel" translatable="yes">Планируемые поставки</property>
+        <signal name="Activated" handler="OnActionShipmentActivated" />
+      </action>
     </action-group>
     <property name="MemberName" />
     <property name="Title" translatable="yes">QS: Спецодежда и имущество</property>
@@ -5274,7 +5280,9 @@
                 <node type="Menuitem" action="ActionStockDocs" />
                 <node type="Menuitem" action="ActionStockBalance" />
                 <node type="Menuitem" action="ActionStockMovements" />
+                <node type="Separator" />
                 <node type="Menuitem" action="ActionWarehouseForecasting" />
+                <node type="Menuitem" action="ActionShipment" />
                 <node type="Separator" />
                 <node type="Menuitem" action="ActionClothingService" />
                 <node type="Menuitem" action="ActionIssuanceSheets" />
@@ -33411,4 +33419,504 @@
       </widget>
     </child>
   </widget>
+  <widget class="Gtk.Bin" id="Workwear.Views.Supply.ShipmentView" design-size="611 425">
+    <property name="MemberName" />
+    <property name="Visible">False</property>
+    <child>
+      <widget class="Gamma.GtkWidgets.yVBox" id="yvbox1">
+        <property name="MemberName" />
+        <property name="WidthRequest">0</property>
+        <property name="HeightRequest">0</property>
+        <property name="BorderWidth">2</property>
+        <child>
+          <widget class="Gamma.GtkWidgets.yHBox" id="yhbox1">
+            <property name="MemberName" />
+            <property name="Spacing">6</property>
+            <child>
+              <widget class="Gamma.GtkWidgets.yButton" id="buttonSave">
+                <property name="MemberName" />
+                <property name="CanFocus">True</property>
+                <property name="Type">TextAndIcon</property>
+                <property name="Icon">stock:gtk-save Menu</property>
+                <property name="Label" translatable="yes">Сохранить</property>
+                <property name="UseUnderline">True</property>
+              </widget>
+              <packing>
+                <property name="Position">0</property>
+                <property name="AutoSize">True</property>
+                <property name="Expand">False</property>
+                <property name="Fill">False</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="Gamma.GtkWidgets.yButton" id="buttonCancel">
+                <property name="MemberName" />
+                <property name="CanFocus">True</property>
+                <property name="Type">TextAndIcon</property>
+                <property name="Icon">stock:gtk-revert-to-saved Menu</property>
+                <property name="Label" translatable="yes">Отменить</property>
+                <property name="UseUnderline">True</property>
+              </widget>
+              <packing>
+                <property name="Position">1</property>
+                <property name="AutoSize">True</property>
+                <property name="Expand">False</property>
+                <property name="Fill">False</property>
+              </packing>
+            </child>
+            <child>
+              <placeholder />
+            </child>
+          </widget>
+          <packing>
+            <property name="Position">0</property>
+            <property name="AutoSize">True</property>
+            <property name="Expand">False</property>
+            <property name="Fill">False</property>
+          </packing>
+        </child>
+        <child>
+          <widget class="Gamma.GtkWidgets.yHBox" id="yhbox2">
+            <property name="MemberName" />
+            <property name="Spacing">6</property>
+            <property name="BorderWidth">3</property>
+            <child>
+              <widget class="Gamma.GtkWidgets.yTable" id="ytable1">
+                <property name="MemberName" />
+                <property name="NRows">5</property>
+                <property name="NColumns">3</property>
+                <property name="RowSpacing">6</property>
+                <property name="ColumnSpacing">6</property>
+                <child>
+                  <placeholder />
+                </child>
+                <child>
+                  <placeholder />
+                </child>
+                <child>
+                  <placeholder />
+                </child>
+                <child>
+                  <placeholder />
+                </child>
+                <child>
+                  <placeholder />
+                </child>
+                <child>
+                  <widget class="Gtk.ScrolledWindow" id="scrolledwindow">
+                    <property name="MemberName" />
+                    <property name="ShadowType">In</property>
+                    <child>
+                      <widget class="Gamma.GtkWidgets.yTextView" id="ytextComment">
+                        <property name="MemberName" />
+                        <property name="CanFocus">True</property>
+                        <property name="ShowScrollbars">True</property>
+                        <property name="AcceptsTab">False</property>
+                        <property name="Text" translatable="yes" />
+                        <property name="WrapMode">WordChar</property>
+                      </widget>
+                    </child>
+                  </widget>
+                  <packing>
+                    <property name="TopAttach">4</property>
+                    <property name="BottomAttach">5</property>
+                    <property name="LeftAttach">1</property>
+                    <property name="RightAttach">2</property>
+                    <property name="AutoSize">False</property>
+                    <property name="XExpand">True</property>
+                    <property name="XFill">True</property>
+                    <property name="XShrink">False</property>
+                    <property name="YExpand">True</property>
+                    <property name="YFill">True</property>
+                    <property name="YShrink">False</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="Gamma.GtkWidgets.yHBox" id="yhbox3">
+                    <property name="MemberName" />
+                    <property name="Spacing">6</property>
+                    <child>
+                      <widget class="Gamma.GtkWidgets.yLabel" id="ylabelNumber">
+                        <property name="MemberName" />
+                        <property name="Xalign">0</property>
+                        <property name="LabelProp" translatable="yes">ylabel1</property>
+                      </widget>
+                      <packing>
+                        <property name="Position">0</property>
+                        <property name="AutoSize">True</property>
+                        <property name="Expand">False</property>
+                        <property name="Fill">False</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <placeholder />
+                    </child>
+                    <child>
+                      <placeholder />
+                    </child>
+                  </widget>
+                  <packing>
+                    <property name="LeftAttach">1</property>
+                    <property name="RightAttach">2</property>
+                    <property name="AutoSize">True</property>
+                    <property name="XOptions">Fill</property>
+                    <property name="YOptions">Fill</property>
+                    <property name="XExpand">False</property>
+                    <property name="XFill">True</property>
+                    <property name="XShrink">False</property>
+                    <property name="YExpand">False</property>
+                    <property name="YFill">True</property>
+                    <property name="YShrink">False</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="Gamma.GtkWidgets.yHBox" id="yhbox6">
+                    <property name="MemberName" />
+                    <property name="Spacing">6</property>
+                    <child>
+                      <widget class="QS.Widgets.GtkUI.DateRangePicker" id="datePeriod">
+                        <property name="MemberName" />
+                        <property name="Events">ButtonPressMask</property>
+                        <property name="StartDate">0</property>
+                        <property name="EndDate">0</property>
+                      </widget>
+                      <packing>
+                        <property name="Position">0</property>
+                        <property name="AutoSize">False</property>
+                        <property name="Expand">False</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <placeholder />
+                    </child>
+                    <child>
+                      <placeholder />
+                    </child>
+                  </widget>
+                  <packing>
+                    <property name="TopAttach">2</property>
+                    <property name="BottomAttach">3</property>
+                    <property name="LeftAttach">1</property>
+                    <property name="RightAttach">2</property>
+                    <property name="AutoSize">True</property>
+                    <property name="XOptions">Fill</property>
+                    <property name="YOptions">Fill</property>
+                    <property name="XExpand">False</property>
+                    <property name="XFill">True</property>
+                    <property name="XShrink">False</property>
+                    <property name="YExpand">False</property>
+                    <property name="YFill">True</property>
+                    <property name="YShrink">False</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="Gamma.GtkWidgets.yLabel" id="ylabel1">
+                    <property name="MemberName" />
+                    <property name="Xalign">1</property>
+                    <property name="LabelProp" translatable="yes">Номер:</property>
+                  </widget>
+                  <packing>
+                    <property name="AutoSize">True</property>
+                    <property name="XOptions">Fill</property>
+                    <property name="YOptions">Fill</property>
+                    <property name="XExpand">False</property>
+                    <property name="XFill">True</property>
+                    <property name="XShrink">False</property>
+                    <property name="YExpand">False</property>
+                    <property name="YFill">True</property>
+                    <property name="YShrink">False</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="Gamma.GtkWidgets.yLabel" id="ylabel10">
+                    <property name="MemberName" />
+                    <property name="Xalign">1</property>
+                    <property name="LabelProp" translatable="yes">Период&lt;span foreground="red"&gt;*&lt;/span&gt;:</property>
+                    <property name="UseMarkup">True</property>
+                  </widget>
+                  <packing>
+                    <property name="TopAttach">2</property>
+                    <property name="BottomAttach">3</property>
+                    <property name="AutoSize">True</property>
+                    <property name="XOptions">Fill</property>
+                    <property name="YOptions">Fill</property>
+                    <property name="XExpand">False</property>
+                    <property name="XFill">True</property>
+                    <property name="XShrink">False</property>
+                    <property name="YExpand">False</property>
+                    <property name="YFill">True</property>
+                    <property name="YShrink">False</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="Gamma.GtkWidgets.yLabel" id="ylabel3">
+                    <property name="MemberName" />
+                    <property name="Xalign">1</property>
+                    <property name="LabelProp" translatable="yes">Пользователь:</property>
+                  </widget>
+                  <packing>
+                    <property name="TopAttach">1</property>
+                    <property name="BottomAttach">2</property>
+                    <property name="AutoSize">True</property>
+                    <property name="XOptions">Fill</property>
+                    <property name="YOptions">Fill</property>
+                    <property name="XExpand">False</property>
+                    <property name="XFill">True</property>
+                    <property name="XShrink">False</property>
+                    <property name="YExpand">False</property>
+                    <property name="YFill">True</property>
+                    <property name="YShrink">False</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="Gamma.GtkWidgets.yLabel" id="ylabel8">
+                    <property name="MemberName" />
+                    <property name="Xalign">1</property>
+                    <property name="Yalign">0</property>
+                    <property name="LabelProp" translatable="yes">Комментарий:</property>
+                  </widget>
+                  <packing>
+                    <property name="TopAttach">4</property>
+                    <property name="BottomAttach">5</property>
+                    <property name="AutoSize">False</property>
+                    <property name="XOptions">Fill</property>
+                    <property name="YOptions">Fill</property>
+                    <property name="XExpand">False</property>
+                    <property name="XFill">True</property>
+                    <property name="XShrink">False</property>
+                    <property name="YExpand">False</property>
+                    <property name="YFill">True</property>
+                    <property name="YShrink">False</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="Gamma.GtkWidgets.yLabel" id="ylabelCreatedBy">
+                    <property name="MemberName" />
+                    <property name="Xalign">0</property>
+                    <property name="LabelProp" translatable="yes">ylabel7</property>
+                  </widget>
+                  <packing>
+                    <property name="TopAttach">1</property>
+                    <property name="BottomAttach">2</property>
+                    <property name="LeftAttach">1</property>
+                    <property name="RightAttach">2</property>
+                    <property name="AutoSize">True</property>
+                    <property name="XOptions">Fill</property>
+                    <property name="YOptions">Fill</property>
+                    <property name="XExpand">False</property>
+                    <property name="XFill">True</property>
+                    <property name="XShrink">False</property>
+                    <property name="YExpand">False</property>
+                    <property name="YFill">True</property>
+                    <property name="YShrink">False</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="Gamma.GtkWidgets.yLabel" id="ylabelStatus">
+                    <property name="MemberName" />
+                    <property name="Xalign">1</property>
+                    <property name="LabelProp" translatable="yes">Статус поставки:</property>
+                  </widget>
+                  <packing>
+                    <property name="TopAttach">3</property>
+                    <property name="BottomAttach">4</property>
+                    <property name="AutoSize">True</property>
+                    <property name="XOptions">Fill</property>
+                    <property name="YOptions">Fill</property>
+                    <property name="XExpand">False</property>
+                    <property name="XFill">True</property>
+                    <property name="XShrink">False</property>
+                    <property name="YExpand">False</property>
+                    <property name="YFill">True</property>
+                    <property name="YShrink">False</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="Gamma.GtkWidgets.yTable" id="ytable2">
+                    <property name="MemberName" />
+                    <property name="NColumns">2</property>
+                    <property name="Homogeneous">True</property>
+                    <property name="RowSpacing">6</property>
+                    <property name="ColumnSpacing">6</property>
+                    <child>
+                      <placeholder />
+                    </child>
+                    <child>
+                      <widget class="Gamma.Widgets.yEnumComboBox" id="yenumcomboboxStatus">
+                        <property name="MemberName" />
+                        <property name="IsTextCombo">True</property>
+                        <property name="Items" translatable="yes" />
+                        <property name="ShowSpecialStateAll">False</property>
+                        <property name="ShowSpecialStateNot">False</property>
+                        <property name="UseShortTitle">False</property>
+                        <property name="DefaultFirst">True</property>
+                      </widget>
+                      <packing>
+                        <property name="AutoSize">True</property>
+                        <property name="XOptions">Fill</property>
+                        <property name="YOptions">Fill</property>
+                        <property name="XExpand">False</property>
+                        <property name="XFill">True</property>
+                        <property name="XShrink">False</property>
+                        <property name="YExpand">False</property>
+                        <property name="YFill">True</property>
+                        <property name="YShrink">False</property>
+                      </packing>
+                    </child>
+                  </widget>
+                  <packing>
+                    <property name="TopAttach">3</property>
+                    <property name="BottomAttach">4</property>
+                    <property name="LeftAttach">1</property>
+                    <property name="RightAttach">2</property>
+                    <property name="AutoSize">True</property>
+                    <property name="XOptions">Fill</property>
+                    <property name="YOptions">Fill</property>
+                    <property name="XExpand">False</property>
+                    <property name="XFill">True</property>
+                    <property name="XShrink">False</property>
+                    <property name="YExpand">False</property>
+                    <property name="YFill">True</property>
+                    <property name="YShrink">False</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="Position">0</property>
+                <property name="AutoSize">False</property>
+              </packing>
+            </child>
+            <child>
+              <placeholder />
+            </child>
+          </widget>
+          <packing>
+            <property name="Position">1</property>
+            <property name="AutoSize">True</property>
+            <property name="Expand">False</property>
+            <property name="Fill">False</property>
+          </packing>
+        </child>
+        <child>
+          <widget class="Gamma.GtkWidgets.yVBox" id="yvbox3">
+            <property name="MemberName" />
+            <property name="Spacing">6</property>
+            <child>
+              <widget class="Gamma.GtkWidgets.yHBox" id="yhbox4">
+                <property name="MemberName" />
+                <property name="Spacing">6</property>
+                <child>
+                  <widget class="Gamma.GtkWidgets.yLabel" id="ylabel6">
+                    <property name="MemberName" />
+                    <property name="LabelProp" translatable="yes">Поставка:</property>
+                  </widget>
+                  <packing>
+                    <property name="Position">0</property>
+                    <property name="AutoSize">True</property>
+                    <property name="Expand">False</property>
+                    <property name="Fill">False</property>
+                  </packing>
+                </child>
+                <child>
+                  <placeholder />
+                </child>
+                <child>
+                  <placeholder />
+                </child>
+              </widget>
+              <packing>
+                <property name="Position">0</property>
+                <property name="AutoSize">True</property>
+                <property name="Expand">False</property>
+                <property name="Fill">False</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="Gtk.ScrolledWindow" id="scrolledwindow2">
+                <property name="MemberName" />
+                <property name="CanFocus">True</property>
+                <property name="ShadowType">In</property>
+                <child>
+                  <widget class="Gamma.GtkWidgets.yTreeView" id="ytreeItems">
+                    <property name="MemberName" />
+                    <property name="CanFocus">True</property>
+                    <property name="ShowScrollbars">True</property>
+                  </widget>
+                </child>
+              </widget>
+              <packing>
+                <property name="Position">1</property>
+                <property name="AutoSize">True</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="Gamma.GtkWidgets.yHBox" id="yhbox5">
+                <property name="MemberName" />
+                <property name="Spacing">6</property>
+                <child>
+                  <widget class="Gamma.GtkWidgets.yButton" id="ybuttonAdd">
+                    <property name="MemberName" />
+                    <property name="CanFocus">True</property>
+                    <property name="Type">TextAndIcon</property>
+                    <property name="Icon">stock:gtk-add Menu</property>
+                    <property name="Label" translatable="yes">Добавить</property>
+                    <property name="UseUnderline">True</property>
+                    <signal name="Clicked" handler="OnYbuttonAddClicked" />
+                  </widget>
+                  <packing>
+                    <property name="Position">0</property>
+                    <property name="AutoSize">True</property>
+                    <property name="Expand">False</property>
+                    <property name="Fill">False</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="Gamma.GtkWidgets.yButton" id="ybuttonDel">
+                    <property name="MemberName" />
+                    <property name="Sensitive">False</property>
+                    <property name="CanFocus">True</property>
+                    <property name="Type">TextAndIcon</property>
+                    <property name="Icon">stock:gtk-remove Menu</property>
+                    <property name="Label" translatable="yes">Удалить</property>
+                    <property name="UseUnderline">True</property>
+                    <signal name="Clicked" handler="OnYbuttonDelClicked" />
+                  </widget>
+                  <packing>
+                    <property name="Position">1</property>
+                    <property name="AutoSize">True</property>
+                    <property name="Expand">False</property>
+                    <property name="Fill">False</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="Gamma.GtkWidgets.yLabel" id="ylabelAmount">
+                    <property name="MemberName" />
+                    <property name="LabelProp" translatable="yes">Количество:</property>
+                    <property name="Justify">Right</property>
+                  </widget>
+                  <packing>
+                    <property name="PackType">End</property>
+                    <property name="Position">2</property>
+                    <property name="AutoSize">True</property>
+                    <property name="Expand">False</property>
+                    <property name="Fill">False</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="Position">2</property>
+                <property name="AutoSize">True</property>
+                <property name="Expand">False</property>
+                <property name="Fill">False</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="Position">2</property>
+            <property name="AutoSize">True</property>
+          </packing>
+        </child>
+      </widget>
+    </child>
+  </widget>
 </stetic-interface>
\ No newline at end of file


Reviews:
user: login: Gankov
state: DISMISSED
author_association: MEMBER
submitted_at: 2025-03-03T11:04:36Z
user: login: Katetim32
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-06T12:29:31Z
user: login: Katetim32
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-06T12:37:10Z
user: login: Katetim32
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-06T12:45:58Z
user: login: Katetim32
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-06T12:54:51Z
user: login: Gankov
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-06T14:20:00Z
user: login: Katetim32
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-07T12:48:21Z
user: login: Gankov
state: CHANGES_REQUESTED
author_association: MEMBER
submitted_at: 2025-03-10T09:49:21Z
user: login: Katetim32
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-10T10:18:40Z
user: login: Katetim32
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-10T10:19:15Z
user: login: Katetim32
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-10T10:31:50Z
user: login: Gankov
state: APPROVED
author_association: MEMBER
submitted_at: 2025-03-11T07:16:06Z

Review comments:
diff_hunk: @@ -727,3 +727,57 @@ alter table stock_income
 
 drop table stock_income_detail;
 
+-- Документ закупки
path: Workwear.Sql/Scripts/2.9.sql
user: login: Gankov
body: Мы 2.9 уже выложили. и Более того даже 2.9.1 Надо делать новый файлик 2.9.2
created_at: 2025-03-03T10:45:49Z
author_association: MEMBER
diff_hunk: @@ -2397,7 +2451,7 @@ SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
 -- -----------------------------------------------------
 START TRANSACTION;
 INSERT INTO `base_parameters` (`name`, `str_value`) VALUES ('product_name', 'workwear');
-INSERT INTO `base_parameters` (`name`, `str_value`) VALUES ('version', '2.9.1');
+INSERT INTO `base_parameters` (`name`, `str_value`) VALUES ('version', '2.9');
path: Workwear.Sql/Scripts/new_empty.sql
user: login: Gankov
body: ЭЭ? тут имеет смысл поменять на 2.9.2.
created_at: 2025-03-03T10:46:39Z
author_association: MEMBER
diff_hunk: @@ -33411,4 +33419,839 @@
       </widget>
     </child>
   </widget>
-</stetic-interface>
\ No newline at end of file
+  <widget class="Gtk.Bin" id="Workwear.Views.Stock.ProcurementView" design-size="603 353">
path: Workwear/gtk-gui/gui.stetic
user: login: Gankov
body: Надо удалить видимо, осталась вьюшка со старым название.
created_at: 2025-03-03T11:02:07Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,73 @@
+﻿using System;
+using Gtk;
+using QS.Views.Dialog;
+using Workwear.Domain.Stock.Documents;
+using Workwear.ViewModels.Stock;
+
+namespace Workwear.Views.Stock {
path: Workwear/Views/Stock/ProcurementView.cs
user: login: Gankov
body: Думаю тоже осталось зря закомичено. надо удалить.
created_at: 2025-03-03T11:02:54Z
author_association: MEMBER
diff_hunk: @@ -727,3 +727,57 @@ alter table stock_income
 
 drop table stock_income_detail;
 
+-- Документ закупки
path: Workwear.Sql/Scripts/2.9.sql
user: login: Katetim32
body: Да, поняла, исправлю.
created_at: 2025-03-06T12:29:31Z
author_association: CONTRIBUTOR
diff_hunk: @@ -2397,7 +2451,7 @@ SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
 -- -----------------------------------------------------
 START TRANSACTION;
 INSERT INTO `base_parameters` (`name`, `str_value`) VALUES ('product_name', 'workwear');
-INSERT INTO `base_parameters` (`name`, `str_value`) VALUES ('version', '2.9.1');
+INSERT INTO `base_parameters` (`name`, `str_value`) VALUES ('version', '2.9');
path: Workwear.Sql/Scripts/new_empty.sql
user: login: Katetim32
body: Этого и не видела даже..исправлю
created_at: 2025-03-06T12:37:10Z
author_association: CONTRIBUTOR
diff_hunk: @@ -33411,4 +33419,839 @@
       </widget>
     </child>
   </widget>
-</stetic-interface>
\ No newline at end of file
+  <widget class="Gtk.Bin" id="Workwear.Views.Stock.ProcurementView" design-size="603 353">
path: Workwear/gtk-gui/gui.stetic
user: login: Katetim32
body: Да, забыла из стетика удалить, сделаю.
created_at: 2025-03-06T12:45:58Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,73 @@
+﻿using System;
+using Gtk;
+using QS.Views.Dialog;
+using Workwear.Domain.Stock.Documents;
+using Workwear.ViewModels.Stock;
+
+namespace Workwear.Views.Stock {
path: Workwear/Views/Stock/ProcurementView.cs
user: login: Katetim32
body: Видимо я удалила локально вьюшку, сделаю.
created_at: 2025-03-06T12:54:51Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,76 @@
+﻿using System;
+using Gtk;
+using QS.Views.Dialog;
+using Workwear.Domain.Supply;
+using Workwear.ViewModels.Supply;
+
+namespace Workwear.Views.Supply {
+	[System.ComponentModel.ToolboxItem(true)]
path: Workwear/Views/Supply/ShipmentView.cs
user: login: Gankov
body: Эта строчка не нужна, потому что этот виджет никуда не вставятся через редактор.
created_at: 2025-03-06T14:16:10Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,76 @@
+﻿using System;
+using Gtk;
+using QS.Views.Dialog;
+using Workwear.Domain.Supply;
+using Workwear.ViewModels.Supply;
+
+namespace Workwear.Views.Supply {
+	[System.ComponentModel.ToolboxItem(true)]
path: Workwear/Views/Supply/ShipmentView.cs
user: login: Katetim32
body: Исправила
created_at: 2025-03-07T12:48:20Z
author_association: CONTRIBUTOR
diff_hunk: @@ -156,5 +158,18 @@ public override bool Save() {
 		}
 
 		#endregion
+
+		public enum StatusOfShipment {
+			[Display(Name="Заказано")]
+			ordered,
path: Workwear/ViewModels/Supply/ShipmentViewModel.cs
user: login: Gankov
body: А можно сделать в C# Стиле как у нас все остальные Enum в программе. С большой буквы.
created_at: 2025-03-10T08:57:49Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,17 @@
+﻿using System.ComponentModel.DataAnnotations;
+
+namespace Workwear.Domain.Supply {
+	public enum ShipmentStatus {
+		[Display(Name="Заказано")]
+		ordered,
path: Workwear.Core/Domain/Supply/ShipmentStatus.cs
user: login: Gankov
body: Хотелось бы иметь с большой буквы
created_at: 2025-03-10T09:37:56Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,54 @@
+﻿-- Документ закупки
+create table shipment
+(
+    id int unsigned auto_increment primary key,
+    start_period date not null,
+    end_period date not null,
+    user_id int unsigned null,
+    comment text null,
+    creation_date datetime null
+);
+create index index_shipment_start_period
+    on shipment (start_period);
+create index index_shipment_end_period
+    on shipment (end_period);
+
+-- Строки документа закупки
+create table shipment_items
+(
+    id int unsigned auto_increment primary key,
+    shipment_id int unsigned not null,
+    nomenclature_id int unsigned not null,
+    quantity int unsigned not null,
+    cost decimal(10, 2) unsigned default 0.00 not null,
+    size_id int unsigned null,
+    height_id int unsigned null,
+    comment varchar(120) null,
+    constraint fk_shipment_items_doc
+        foreign key (shipment_id) references shipment (id)
+            on update cascade on delete cascade,
+    constraint fk_shipment_items_nomenclature
+        foreign key (nomenclature_id) references nomenclature (id)
+            on update cascade,
+    constraint fk_shipment_items_size_id
+        foreign key (size_id) references sizes (id)
+            on update cascade,
+    constraint fk_shipment_items_height_id
+        foreign key (height_id) references sizes (id)
+            on update cascade
+);
+create index index_shipment_items_doc
+    on shipment_items (shipment_id);
+
+create index index_shipment_items_height
+    on shipment_items (height_id);
+
+create index index_shipment_items_nomenclature
+    on shipment_items (nomenclature_id);
+
+create index index_shipment_items_size
+    on shipment_items (size_id);
+
+alter table shipment
+	add status text not null default 'ordered' after end_period;
path: Workwear.Sql/Scripts/2.9.2.sql
user: login: Gankov
body: У нас в проекте принято использовать Enum. Ну и поле text оно же огромное.
И это можно вынести в основное создание таблицы и не доп командой.
created_at: 2025-03-10T09:41:32Z
author_association: MEMBER
diff_hunk: @@ -508,6 +509,32 @@ string ForegroundColor(EmployeeJournalNode n)
 					.Finish()
 			);
 			#endregion
+
+			#region Supply
+
+			TreeViewColumnsConfigFactory.Register<ShipmentJournalViewModel>(
+				(jvm) => FluentColumnsConfig<ShipmentJournalNode>.Create()
+					.AddColumn("ИД").AddTextRenderer(node => $"{node.Id}").SearchHighlight()
+					.AddColumn("Период").AddTextRenderer(node=>$"{node.StartPeriod.ToShortDateString()} - {node.EndPeriod.ToShortDateString()}")
+					.AddColumn("Создал").AddTextRenderer(node=>node.Author).SearchHighlight()
+					.AddColumn("Дата создания").AddTextRenderer(node=>node.CreationDate.ToShortDateString())
+					.AddColumn("Комментарий").AddTextRenderer(node=>node.Comment).SearchHighlight()
+					.AddColumn("Статус").AddTextRenderer(node=>node.StatusText)
+					.RowCells().AddSetter<Gtk.CellRendererText>((c, x) => c.Foreground = ForegroundColorShipment(x))
+					.Finish()
+				);
+			string ForegroundColorShipment(ShipmentJournalNode n)
+			{
+				if(n.StatusText=="Отменено"||n.StatusText=="Получено")
path: Workwear/Journal/JournalsColumnsConfigs.cs
user: login: Gankov
body: Эх, ну почему используется отображаемое значение? А если кто-то поменяет. Он наврали это место найдет. Будет баг. Надо использовать Enum.
created_at: 2025-03-10T09:45:22Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,17 @@
+﻿using System.ComponentModel.DataAnnotations;
+
+namespace Workwear.Domain.Supply {
+	public enum ShipmentStatus {
+		[Display(Name="Заказано")]
+		ordered,
path: Workwear.Core/Domain/Supply/ShipmentStatus.cs
user: login: Katetim32
body: Переделаю.
created_at: 2025-03-10T10:18:40Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,54 @@
+﻿-- Документ закупки
+create table shipment
+(
+    id int unsigned auto_increment primary key,
+    start_period date not null,
+    end_period date not null,
+    user_id int unsigned null,
+    comment text null,
+    creation_date datetime null
+);
+create index index_shipment_start_period
+    on shipment (start_period);
+create index index_shipment_end_period
+    on shipment (end_period);
+
+-- Строки документа закупки
+create table shipment_items
+(
+    id int unsigned auto_increment primary key,
+    shipment_id int unsigned not null,
+    nomenclature_id int unsigned not null,
+    quantity int unsigned not null,
+    cost decimal(10, 2) unsigned default 0.00 not null,
+    size_id int unsigned null,
+    height_id int unsigned null,
+    comment varchar(120) null,
+    constraint fk_shipment_items_doc
+        foreign key (shipment_id) references shipment (id)
+            on update cascade on delete cascade,
+    constraint fk_shipment_items_nomenclature
+        foreign key (nomenclature_id) references nomenclature (id)
+            on update cascade,
+    constraint fk_shipment_items_size_id
+        foreign key (size_id) references sizes (id)
+            on update cascade,
+    constraint fk_shipment_items_height_id
+        foreign key (height_id) references sizes (id)
+            on update cascade
+);
+create index index_shipment_items_doc
+    on shipment_items (shipment_id);
+
+create index index_shipment_items_height
+    on shipment_items (height_id);
+
+create index index_shipment_items_nomenclature
+    on shipment_items (nomenclature_id);
+
+create index index_shipment_items_size
+    on shipment_items (size_id);
+
+alter table shipment
+	add status text not null default 'ordered' after end_period;
path: Workwear.Sql/Scripts/2.9.2.sql
user: login: Katetim32
body: Да, поняла, сделаю через enum.
created_at: 2025-03-10T10:19:14Z
author_association: CONTRIBUTOR
diff_hunk: @@ -508,6 +509,32 @@ string ForegroundColor(EmployeeJournalNode n)
 					.Finish()
 			);
 			#endregion
+
+			#region Supply
+
+			TreeViewColumnsConfigFactory.Register<ShipmentJournalViewModel>(
+				(jvm) => FluentColumnsConfig<ShipmentJournalNode>.Create()
+					.AddColumn("ИД").AddTextRenderer(node => $"{node.Id}").SearchHighlight()
+					.AddColumn("Период").AddTextRenderer(node=>$"{node.StartPeriod.ToShortDateString()} - {node.EndPeriod.ToShortDateString()}")
+					.AddColumn("Создал").AddTextRenderer(node=>node.Author).SearchHighlight()
+					.AddColumn("Дата создания").AddTextRenderer(node=>node.CreationDate.ToShortDateString())
+					.AddColumn("Комментарий").AddTextRenderer(node=>node.Comment).SearchHighlight()
+					.AddColumn("Статус").AddTextRenderer(node=>node.StatusText)
+					.RowCells().AddSetter<Gtk.CellRendererText>((c, x) => c.Foreground = ForegroundColorShipment(x))
+					.Finish()
+				);
+			string ForegroundColorShipment(ShipmentJournalNode n)
+			{
+				if(n.StatusText=="Отменено"||n.StatusText=="Получено")
path: Workwear/Journal/JournalsColumnsConfigs.cs
user: login: Katetim32
body: Согласна, переделаю.
created_at: 2025-03-10T10:31:50Z
author_association: CONTRIBUTOR

PR comments:
user: login: Gankov
created_at: 2025-03-03T11:32:05Z
body: Еще просьба сразу сделать в документ статут поставки.
Enum со следующими значениям: заказано, в пути, ожидает оплаты, отменено, Получено
И в списке поставок, подсвечивать их разными цветами.
Серым подсвечиваем поставки, отмененные и полученные
Красным, если дата окончания уже прошла, то есть поставка просрочена.
Оранжевым, если мы находимся в периоде поставки.
Остальное пока черным.
author_association: MEMBER
user: login: Katetim32
created_at: 2025-03-06T12:59:53Z
body: Подсвечиваем всю строку? Или достаточно айдишник поставки?
author_association: CONTRIBUTOR
user: login: Katetim32
created_at: 2025-03-06T13:13:35Z
body: И правильно ли я поняла, что статус поставки нужно добавить в журнал? Чтобы уже у созданного документа сразу в журнале менять статус
author_association: CONTRIBUTOR
user: login: Katetim32
created_at: 2025-03-06T13:14:55Z
body: Или может и при создании статус выбирать, и в журнале возможность его менять..
author_association: CONTRIBUTOR
user: login: Gankov
created_at: 2025-03-06T13:19:24Z
body: Еще просьба сразу сделать в документ статут поставки.
Enum со следующими значениям: заказано, в пути, ожидает оплаты, отменено, Получено
И в списке поставок, подсвечивать их разными цветами.
Серым подсвечиваем поставки, отмененные и полученные
Красным, если дата окончания уже прошла, то есть поставка просрочена.
Оранжевым, если мы находимся в периоде поставки.
Остальное пока черным.
author_association: MEMBER
user: login: Gankov
created_at: 2025-03-06T14:07:20Z
body: > Подсвечиваем всю строку? Или достаточно айдишник поставки?

Лучше всю строку.
author_association: MEMBER
user: login: Gankov
created_at: 2025-03-06T14:09:14Z
body: > И правильно ли я поняла, что статус поставки нужно добавить в журнал? Чтобы уже у созданного документа сразу в журнале менять статус

Нет в журнале не надо менять статус. покрайней мере пока, может если мы поймем что это очень удобно потом добавил. Но сейчас, давай через открытие диалога статус менять. Ну хотя сделай как тебе проще.
author_association: MEMBER
user: login: Gankov
created_at: 2025-03-06T14:12:06Z
body: > Или может и при создании статус выбирать, и в журнале возможность его менять..

Да можно и при создании выбирать. Почему нет.
author_association: MEMBER
user: login: Katetim32
created_at: 2025-03-06T14:58:35Z
body: А статус будет обязательным для документа? Или пользователь может выбрать в статусе "нет" например?
author_association: CONTRIBUTOR
user: login: Gankov
created_at: 2025-03-06T15:03:54Z
body: Да обязательный, статус по умолчанию заказано.
author_association: MEMBER
user: login: Katetim32
created_at: 2025-03-07T11:42:32Z
body: Исправляю статусы.
author_association: CONTRIBUTOR
user: login: Katetim32
created_at: 2025-03-07T12:48:48Z
body: Закончила со статусами.
author_association: CONTRIBUTOR