USE [Database]
GO

IF OBJECT_ID(N'[Functions].[product_information]') IS NOT NULL
  DROP FUNCTION [Functions].[product_information];
GO
CREATE FUNCTION [Functions].[product_information] ()
RETURNS TABLE
AS
  RETURN
  SELECT [E].[id], [E].[name] AS [product_name], [T].[name] AS [type_name], [A].[attribute_id], [AN].[name], [V].[value] 
  FROM [Tables].[products] AS [E]
  JOIN [Tables].[product_types] AS [T]
    ON [T].[id] = [E].[product_type_id]
  JOIN [Tables].[product_attributes] AS [A]
    ON [A].[product_id] = [E].[id]
  JOIN [Tables].[attributes] AS [AN]
    ON [AN].[id] = [A].[attribute_id]
  LEFT JOIN [Tables].[product_values] AS [V]
    ON [V].[product_id] = [A].[product_id]
    AND [V].[attribute_id] = [A].[attribute_id]
GO

IF OBJECT_ID(N'[Functions].[product_inflow_records_information]') IS NOT NULL
  DROP FUNCTION [Functions].[product_inflow_records_information];
GO
CREATE FUNCTION [Functions].[product_inflow_records_information] ()
RETURNS TABLE
AS
RETURN
  SELECT [pir].[id], [V].[value], [S].[name], [pir].[count], [pir].[full_price], [pir].[datetime]
  FROM [Tables].[product_inflow_records] AS [pir]
  JOIN [Tables].[product_values] AS [V]
    ON [V].[id] = [pir].[barcode_product_value_id]
  JOIN [Tables].[suppliers] AS [S]
    ON [S].[id] = [pir].supplier_id
GO

--<< 0
SELECT *
FROM [Functions].[product_information]();

--<< 1
DECLARE @first_barcode_attribute_id AS INT,
        @second_barcode_attribute_id AS INT;

DECLARE @barcode_attribute_id AS INT;
SET @barcode_attribute_id =
 (SELECT [id]
  FROM [Tables].[attributes] 
  WHERE [name] = N'Barcode');

EXECUTE [Procedures].[insert_barcode]
@product_id = 1, 
@barcode_attribute_id = @barcode_attribute_id,
@barcode = N'7145621037931',
@inserted_barcode_attribute_id = @first_barcode_attribute_id OUTPUT;

SELECT *
FROM [Functions].[product_information]();

--<< 2
BEGIN TRY
  EXECUTE [Procedures].[insert_barcode] 1, @barcode_attribute_id, N'7145621037931';
END TRY
BEGIN CATCH -- The barcode is not unique
  PRINT N'The error occurred - the right case'
END CATCH

BEGIN TRY
  EXECUTE [Procedures].[insert_barcode] 1, @barcode_attribute_id, N'0289713447192';
END TRY
BEGIN CATCH -- The barcode is already exsist
  PRINT N'The error occurred - the right case'
END CATCH

EXECUTE [Procedures].[insert_barcode] 2, @barcode_attribute_id, N'0000000000000', @inserted_barcode_attribute_id = @second_barcode_attribute_id OUTPUT;
EXECUTE [Procedures].[insert_barcode] 3, @barcode_attribute_id;
EXECUTE [Procedures].[insert_barcode] 4, @barcode_attribute_id;

SELECT *
FROM [Functions].[product_information]();

--<< 3
DECLARE 
  @buffer_date_1 AS DATE,
  @buffer_date_2 AS DATE,
  @buffer_date_3 AS DATE,
  @buffer_date_4 AS DATE,
  @buffer_date_5 AS DATE;
  
SET @buffer_date_1 = CAST(N'1900-01-01' AS DATE);
SET @buffer_date_2 = CAST(N'1900-01-02' AS DATE);
SET @buffer_date_3 = CAST(N'1900-01-03' AS DATE);
SET @buffer_date_4 = CAST(N'1900-01-04' AS DATE);
SET @buffer_date_5 = CAST(N'1900-01-05' AS DATE);

EXECUTE [Procedures].[insert_product_inflow_record]
  @barcode_product_value_id = @first_barcode_attribute_id,
  @barcode_product_attribute_id = @barcode_attribute_id,
  @supplier_id = 1,
  @count = 2,
  @full_price = 3000,
  @datetime = @buffer_date_1;

EXECUTE [Procedures].[insert_product_inflow_record]
  @barcode_product_value_id = @second_barcode_attribute_id,
  @barcode_product_attribute_id = @barcode_attribute_id,
  @supplier_id = 3,
  @count = 50,
  @full_price = 1600,
  @datetime = @buffer_date_2;

SELECT *
FROM [Functions].[product_inflow_records_information]();

--<< 4
BEGIN TRY
  EXECUTE [Procedures].[insert_product_outflow_record] @second_barcode_attribute_id, 5, @buffer_date_2;
END TRY
BEGIN CATCH -- Price not specified
  PRINT N'The error occurred - the right case'
END CATCH

EXECUTE [Procedures].[insert_price_history_record] 2, @buffer_date_1, 40 -- Жевательная резинка Orbit Mega Клубника, без сахара, 16,4 г
EXECUTE [Procedures].[insert_product_outflow_record] @second_barcode_attribute_id, 5, @buffer_date_2;

SELECT [Functions].[product_with_barcode_stock](@barcode_attribute_id, @second_barcode_attribute_id);

EXECUTE [Procedures].[insert_price_history_record] 2, @buffer_date_3, 45 -- Жевательная резинка Orbit Mega Клубника, без сахара, 16,4 г
EXECUTE [Procedures].[insert_product_outflow_record] @second_barcode_attribute_id, 10, @buffer_date_4;

SELECT [Functions].[product_with_barcode_stock](@barcode_attribute_id, @second_barcode_attribute_id);
EXECUTE [Procedures].[details_of_product_outflow_records];

--<< 5
EXECUTE [Procedures].[insert_product_write_off_record] @second_barcode_attribute_id, 1, 5, @buffer_date_5; -- Вышел срок годности

SELECT *
FROM [Tables].[product_write_off_records];

SELECT [Functions].[product_with_barcode_stock](@barcode_attribute_id, @second_barcode_attribute_id);

BEGIN TRY
  INSERT INTO [Tables].[product_outflow_records]([barcode_product_value_id], [count], [datetime])
  VALUES(@first_barcode_attribute_id, 3, @buffer_date_1);
END TRY
BEGIN CATCH
  PRINT N'The error occurred - the right case'
END CATCH

DROP FUNCTION [Functions].[product_information];
DROP FUNCTION [Functions].[product_inflow_records_information];