CREATE FUNCTION pg_catalog.text(integer) RETURNS text STRICT IMMUTABLE LANGUAGE SQL AS 'SELECT textin(int4out($1));';
CREATE CAST (integer AS text) WITH FUNCTION pg_catalog.text(integer) AS IMPLICIT;
CREATE FUNCTION pg_catalog.text(smallint) RETURNS text STRICT IMMUTABLE LANGUAGE SQL AS 'SELECT textin(int2out($1));';
CREATE CAST (smallint AS text) WITH FUNCTION pg_catalog.text(smallint) AS IMPLICIT;
CREATE FUNCTION pg_catalog.text(oid) RETURNS text STRICT IMMUTABLE LANGUAGE SQL AS 'SELECT textin(oidout($1));';
CREATE CAST (oid AS text) WITH FUNCTION pg_catalog.text(oid) AS IMPLICIT;
CREATE FUNCTION pg_catalog.text(date) RETURNS text STRICT IMMUTABLE LANGUAGE SQL AS 'SELECT textin(date_out($1));';
CREATE CAST (date AS text) WITH FUNCTION pg_catalog.text(date) AS IMPLICIT;
CREATE FUNCTION pg_catalog.text(double precision) RETURNS text STRICT IMMUTABLE LANGUAGE SQL AS 'SELECT textin(float8out($1));';
CREATE CAST (double precision AS text) WITH FUNCTION pg_catalog.text(double precision) AS IMPLICIT;
CREATE FUNCTION pg_catalog.text(real) RETURNS text STRICT IMMUTABLE LANGUAGE SQL AS 'SELECT textin(float4out($1));';
CREATE CAST (real AS text) WITH FUNCTION pg_catalog.text(real) AS IMPLICIT;
CREATE FUNCTION pg_catalog.text(time with time zone) RETURNS text STRICT IMMUTABLE LANGUAGE SQL AS 'SELECT textin(timetz_out($1));';
CREATE CAST (time with time zone AS text) WITH FUNCTION pg_catalog.text(time with time zone) AS IMPLICIT;
CREATE FUNCTION pg_catalog.text(time without time zone) RETURNS text STRICT IMMUTABLE LANGUAGE SQL AS 'SELECT textin(time_out($1));';
CREATE CAST (time without time zone AS text) WITH FUNCTION pg_catalog.text(time without time zone) AS IMPLICIT;
CREATE FUNCTION pg_catalog.text(timestamp with time zone) RETURNS text STRICT IMMUTABLE LANGUAGE SQL AS 'SELECT textin(timestamptz_out($1));';
CREATE CAST (timestamp with time zone AS text) WITH FUNCTION pg_catalog.text(timestamp with time zone) AS IMPLICIT;
CREATE FUNCTION pg_catalog.text(interval) RETURNS text STRICT IMMUTABLE LANGUAGE SQL AS 'SELECT textin(interval_out($1));';
CREATE CAST (interval AS text) WITH FUNCTION pg_catalog.text(interval) AS IMPLICIT;
CREATE FUNCTION pg_catalog.text(bigint) RETURNS text STRICT IMMUTABLE LANGUAGE SQL AS 'SELECT textin(int8out($1));';
CREATE CAST (bigint AS text) WITH FUNCTION pg_catalog.text(bigint) AS IMPLICIT;
CREATE FUNCTION pg_catalog.text(numeric) RETURNS text STRICT IMMUTABLE LANGUAGE SQL AS 'SELECT textin(numeric_out($1));';
CREATE CAST (numeric AS text) WITH FUNCTION pg_catalog.text(numeric) AS IMPLICIT;
CREATE FUNCTION pg_catalog.text(timestamp without time zone) RETURNS text STRICT IMMUTABLE LANGUAGE SQL AS 'SELECT textin(timestamp_out($1));';
CREATE CAST (timestamp without time zone AS text) WITH FUNCTION pg_catalog.text(timestamp without time zone) AS IMPLICIT;

DROP TABLE IF EXISTS clerks CASCADE;
DROP TABLE IF EXISTS groups CASCADE;
DROP TABLE IF EXISTS customers CASCADE;
DROP TABLE IF EXISTS products CASCADE;
DROP TABLE IF EXISTS payment_medias CASCADE;
DROP TABLE IF EXISTS product_groups CASCADE;
DROP TABLE IF EXISTS product_daily_specials CASCADE;
DROP TABLE IF EXISTS product_menus CASCADE;
DROP TABLE IF EXISTS sales_headers CASCADE;
DROP TABLE IF EXISTS sales_headers_aux CASCADE;
DROP TABLE IF EXISTS sales_details CASCADE;
DROP TABLE IF EXISTS sales_hashes CASCADE;
DROP TABLE IF EXISTS sales_hashes_products CASCADE;
DROP TABLE IF EXISTS sales_payments CASCADE;
DROP TABLE IF EXISTS sales_payments_aux CASCADE;
DROP TABLE IF EXISTS cashdrawer_opens CASCADE;
DROP TABLE IF EXISTS time_clock CASCADE;
DROP TABLE IF EXISTS lists CASCADE;
DROP TABLE IF EXISTS products_lists CASCADE;
DROP TABLE IF EXISTS vouchers CASCADE;
DROP TABLE IF EXISTS transfers CASCADE;
DROP TABLE IF EXISTS transfer_products CASCADE;

CREATE SEQUENCE transfers_seq INCREMENT BY 1 NO MAXVALUE NO MINVALUE CACHE 1;
CREATE SEQUENCE clerks_seq INCREMENT BY 1 NO MAXVALUE NO MINVALUE CACHE 1;
CREATE SEQUENCE customers_seq INCREMENT BY 1 NO MAXVALUE NO MINVALUE CACHE 1;
CREATE SEQUENCE groups_seq INCREMENT BY 1 NO MAXVALUE NO MINVALUE CACHE 1;
CREATE SEQUENCE products_seq INCREMENT BY 1 NO MAXVALUE NO MINVALUE CACHE 1;
CREATE SEQUENCE payment_medias_seq INCREMENT BY 1 NO MAXVALUE NO MINVALUE CACHE 1;
CREATE SEQUENCE sales_headers_seq INCREMENT BY 1 NO MAXVALUE NO MINVALUE CACHE 1;
CREATE SEQUENCE sales_headers_aux_seq INCREMENT BY 1 NO MAXVALUE NO MINVALUE CACHE 1;
CREATE SEQUENCE sales_hashes_seq INCREMENT BY 1 NO MAXVALUE NO MINVALUE CACHE 1;
CREATE SEQUENCE sales_payments_seq INCREMENT BY 1 NO MAXVALUE NO MINVALUE CACHE 1;
CREATE SEQUENCE sales_payments_aux_seq INCREMENT BY 1 NO MAXVALUE NO MINVALUE CACHE 1;
CREATE SEQUENCE cashdrawer_opens_seq INCREMENT BY 1 NO MAXVALUE NO MINVALUE CACHE 1;
CREATE SEQUENCE time_clock_seq INCREMENT BY 1 NO MAXVALUE NO MINVALUE CACHE 1;
CREATE SEQUENCE lists_seq INCREMENT BY 1 NO MAXVALUE NO MINVALUE CACHE 1;
CREATE SEQUENCE vouchers_seq INCREMENT BY 1 NO MAXVALUE NO MINVALUE CACHE 1;

CREATE TABLE clerks (
  id INT NOT NULL,
  login VARCHAR(20),
  passwd VARCHAR(20),
  can_login INTEGER DEFAULT 1,
  button_color VARCHAR(10),
  can_session_totals INTEGER DEFAULT 1,
  can_daily_simple INTEGER DEFAULT 1,
  can_daily_totals INTEGER DEFAULT 1,
  can_do_returns INTEGER DEFAULT 1,
  used_for_training INTEGER DEFAULT 0,
  can_change_prices INTEGER DEFAULT 1,
  can_use_discounts INTEGER DEFAULT 1,
  can_open_drawer INTEGER DEFAULT 1,
  skin VARCHAR(10) DEFAULT 'EN',
  deleted INTEGER DEFAULT 0,
  default_area INTEGER DEFAULT 0,
  can_close_day INTEGER DEFAULT 1,
  can_transfer_products INTEGER DEFAULT 0,
  can_void_products INTEGER DEFAULT 0,
  can_edit_tables INTEGER DEFAULT 0,
  signon_key VARCHAR,
  cashier INTEGER DEFAULT 0,
  can_do_open_discounts INTEGER DEFAULT 0,
  can_transfer_tables INTEGER DEFAULT 0,
  cant_use_others_tables INTEGER DEFAULT 0,
  cant_close_checks INTEGER DEFAULT 0,
  open_blocked_areas INTEGER DEFAULT 0,
  see_historical_sales INTEGER DEFAULT 0,
  can_login INTEGER DEFAULT 1,
  cant_suspend INTEGER DEFAULT 0,
  cant_print_bill INTEGER DEFAULT 0,
  cant_print_bill_internal INTEGER DEFAULT 0,
  consumption_discount NUMERIC DEFAULT 0,
  PRIMARY KEY (id)
);

CREATE TABLE customers (
  id INT NOT NULL,
  name VARCHAR(150),
  card_number VARCHAR(100),
  nif VARCHAR(100),
  discount NUMERIC DEFAULT 0,
  address VARCHAR(255),
  postal_code VARCHAR(20),
  city VARCHAR(100),
  deleted INTEGER DEFAULT 0,
  PRIMARY KEY (id)
);

CREATE TABLE groups (
  id INT NOT NULL,
  name VARCHAR(150),
  button_color VARCHAR(10),
  button_bg_color VARCHAR(10),
  parent INTEGER DEFAULT 0,
  priority INTEGER DEFAULT 0,
  print_priority INTEGER DEFAULT 0,
  deleted INTEGER DEFAULT 0,
  button_bg_color varchar(10),
  image varchar(20),
  PRIMARY KEY (id)
);

CREATE TABLE products (
  id INT NOT NULL,
  name VARCHAR(150),
  button_text VARCHAR(50),
  grupo INTEGER DEFAULT 0,
  button_color VARCHAR(10),
  button_bg_color VARCHAR(10),
  sell_price1 NUMERIC DEFAULT 0,
  sell_price2 NUMERIC DEFAULT 0,
  sell_price3 NUMERIC DEFAULT 0,
  sell_price4 NUMERIC DEFAULT 0,
  sell_price5 NUMERIC DEFAULT 0,
  sell_price_menu NUMERIC DEFAULT 0,
  sell_vat1 NUMERIC DEFAULT 0,
  sell_vat2 NUMERIC DEFAULT 0,
  is_weight INTEGER DEFAULT 0,
  barcode VARCHAR(100) DEFAULT 0,
  ask_price INTEGER DEFAULT 0,
  printing_zone VARCHAR(20),
  tare NUMERIC DEFAULT 0,
  is_menu INTEGER DEFAULT 0,
  is_extra INTEGER DEFAULT 0,
  priority INTEGER DEFAULT 0,
  print_priority INTEGER DEFAULT 0,
  is_message INTEGER DEFAULT 0,
  parent_product INTEGER DEFAULT 0,
  vat_isention VARCHAR(150),
  time_config VARCHAR(50) DEFAULT 0,
  cost_price NUMERIC DEFAULT 0,
  deleted INTEGER DEFAULT 0,
  require_extras NUMERIC DEFAULT 0,
  qtty_factor NUMERIC DEFAULT 0,
  which_extras VARCHAR(255),
  button_bg_color varchar(10),
  handy_plu integer default 0,
  image varchar(20),
  PRIMARY KEY (id)
);

CREATE TABLE payment_medias (
  id INT NOT NULL,
  name VARCHAR(150) NOT NULL,
  is_default INTEGER DEFAULT 0,
  deleted INTEGER DEFAULT 0,
  PRIMARY KEY (id)
);

CREATE TABLE product_groups (
  product_id INTEGER NOT NULL,
  group_id INTEGER NOT NULL,
  UNIQUE (product_id, group_id)
);

CREATE TABLE product_daily_specials (
  product_id INTEGER NOT NULL REFERENCES products(id),
  price NUMERIC DEFAULT 0,
  max_qtty INTEGER DEFAULT 0
);

CREATE TABLE product_menus (
  product_menu_id INTEGER NOT NULL,
  product_id INTEGER NOT NULL,
  step_number INTEGER DEFAULT 1,
  extra_price NUMERIC DEFAULT 0
);

CREATE TABLE sales_headers (
  id INT NOT NULL,
  timestamp TIMESTAMP NOT NULL,
  date TIMESTAMP NOT NULL,
  date_closed TIMESTAMP NOT NULL,
  business_date DATE NOT NULL,
  hour VARCHAR(8) NOT NULL DEFAULT '00:00:00',
  doc_type INTEGER NOT NULL DEFAULT 1,
  fo_doc_number VARCHAR(50) NOT NULL,
  value NUMERIC DEFAULT 0,
  discount NUMERIC DEFAULT 0,
  clerk_open INTEGER NOT NULL REFERENCES clerks(id),
  clerk_close INTEGER NOT NULL REFERENCES clerks(id),
  station_open INTEGER NOT NULL DEFAULT 0,
  station_close INTEGER NOT NULL DEFAULT 0,
  area INTEGER NOT NULL DEFAULT 0,
  clerk_open_name VARCHAR(30),
  clerk_close_name VARCHAR(30),
  customer VARCHAR(150),
  customer_nif INTEGER,
  persons_number INTEGER DEFAULT 1,
  tip NUMERIC DEFAULT 0,
  service_charge NUMERIC DEFAULT 0,
  cashier INTEGER DEFAULT 0,
  table_num INTEGER DEFAULT 0,
  PRIMARY KEY (id)
);

CREATE INDEX idx_sales_headers_business_date ON sales_headers (business_date);
CREATE INDEX idx_sales_headers_doc_type ON sales_headers (doc_type);
CREATE INDEX idx_sales_headers_fo_doc_number ON sales_headers (fo_doc_number);
CREATE INDEX idx_sales_headers_clerk_close ON sales_headers (clerk_close);
CREATE INDEX idx_sales_headers_customer ON sales_headers (customer);
CREATE INDEX idx_sales_headers_customer_nif ON sales_headers (customer_nif);

CREATE TABLE sales_headers_aux (
  id INT NOT NULL,
  header INTEGER NOT NULL REFERENCES sales_headers(id),
  key_name VARCHAR(100),
  key_value VARCHAR(100),
  PRIMARY KEY (id)
);

CREATE TABLE sales_details (
  header INTEGER NOT NULL REFERENCES sales_headers(id),
  product INTEGER NOT NULL REFERENCES products(id),
  clerk INTEGER NOT NULL REFERENCES clerks(id),
  hour VARCHAR(8) NOT NULL DEFAULT '00:00:00',
  quantity NUMERIC DEFAULT 0,
  price NUMERIC DEFAULT 0,
  discount NUMERIC DEFAULT 0,
  offer NUMERIC DEFAULT 0,
  vat NUMERIC DEFAULT 0,
  station INTEGER NOT NULL DEFAULT 0,
  operation_type INTEGER NOT NULL DEFAULT 0,
  product_name VARCHAR(30),
  clerk_name VARCHAR(30),
  free_text VARCHAR(255),
  price_wo_vat NUMERIC DEFAULT 0,
  inside_menu INTEGER DEFAULT 0,
  gb_identifier VARCHAR(30) NOT NULL,
  department VARCHAR(150),
  price_used INTEGER DEFAULT 1
);

CREATE INDEX sales_details_header ON sales_details (header);
CREATE INDEX sales_details_operation_type ON sales_details (operation_type);

CREATE TABLE sales_hashes (
  id INT NOT NULL,
  header INTEGER REFERENCES sales_headers(id),
  gb_identifier_header VARCHAR(30) NOT NULL,
  business_date DATE NOT NULL,
  system_entry_date DATE NOT NULL,
  doc_type INTEGER NOT NULL DEFAULT 1,
  fo_doc_number VARCHAR(50) NOT NULL,
  value NUMERIC DEFAULT 0 NOT NULL,
  hash VARCHAR(172) NOT NULL,
  hash_small VARCHAR(15) NOT NULL,
  PRIMARY KEY (id)
);

CREATE INDEX idx_sales_hashes_doc_type ON sales_hashes (doc_type);
CREATE INDEX idx_sales_hashes_header ON sales_hashes (header);
CREATE INDEX idx_sales_hashes_gb_identifier_header ON sales_hashes (gb_identifier_header);

CREATE TABLE sales_hashes_products (
  hash_id INTEGER REFERENCES sales_hashes(id),
  gb_identifier_detail VARCHAR(30)
);

CREATE INDEX idx_sales_hashes_products_gb_identifier_detail ON sales_hashes_products (gb_identifier_detail);

CREATE TABLE sales_payments (
  id INT NOT NULL,
  header INTEGER NOT NULL REFERENCES sales_headers(id),
  payment_media VARCHAR(50) NOT NULL,
  value NUMERIC DEFAULT 0,
  obs VARCHAR(255),
  PRIMARY KEY (id)
);

CREATE TABLE sales_payments_aux (
  id INT NOT NULL,
  payment INTEGER NOT NULL REFERENCES sales_payments(id),
  key_name VARCHAR(100),
  key_value VARCHAR(100),
  PRIMARY KEY (id)
);

CREATE TABLE cashdrawer_opens (
  id INT NOT NULL,
  date TIMESTAMP NOT NULL,
  station_number INTEGER,
  clerk INTEGER,
  clerk_name VARCHAR,
  PRIMARY KEY (id)
);

CREATE TABLE time_clock (
  id INT NOT NULL,
  date DATE NOT NULL,
  hour VARCHAR(8) NOT NULL DEFAULT '00:00:00',
  station_number INTEGER,
  clerk INTEGER,
  clerk_name VARCHAR,
  operation VARCHAR,
  description VARCHAR,
  PRIMARY KEY (id)
);

CREATE TABLE lists (
  id INT NOT NULL,
  kind VARCHAR NOT NULL,
  list_name VARCHAR NOT NULL,
  start_hour VARCHAR,
  end_hour VARCHAR,
  weekdays VARCHAR,
  for_reporting INTEGER DEFAULT 0,
  PRIMARY KEY (id)
);

CREATE TABLE products_lists (
  list_id INTEGER NOT NULL REFERENCES lists(id),
  kind VARCHAR NOT NULL,
  product_id INTEGER NOT NULL REFERENCES products(id)
);

CREATE TABLE vouchers (
  id INT NOT NULL,
  business_date DATE NOT NULL,
  date TIMESTAMP NOT NULL,
  date_expiration DATE,
  doc_origin VARCHAR,
  doc_generated VARCHAR,
  was_used_already INTEGER DEFAULT 0,
  value NUMERIC DEFAULT 0,
  external_voucher INTEGER DEFAULT 0,
  external_id VARCHAR,
  date_used DATE,
  PRIMARY KEY (id)
);

CREATE TABLE transfers (
  id INT NOT NULL,
  date DATE NOT NULL,
  hour VARCHAR(8) NOT NULL DEFAULT '00:00:00',
  station INTEGER,
  clerk INTEGER,
  clerk_name VARCHAR,
  area_from INTEGER,
  area_to INTEGER,
  table_from VARCHAR(5),
  table_to VARCHAR(5),
  PRIMARY KEY (id)
);

CREATE TABLE transfer_products (
  transfer_id INTEGER NOT NULL REFERENCES transfers(id),
  product_id INTEGER NOT NULL REFERENCES products(id),
  product_name VARCHAR,
  quantity NUMERIC DEFAULT 0
);

CREATE TABLE product_names (
  product_id INTEGER NOT NULL REFERENCES products(id),
  language VARCHAR NOT NULL,
  value VARCHAR NOT NULL
);

