OpenPartsLibrary 0.1.7__tar.gz → 0.1.9__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: OpenPartsLibrary
3
- Version: 0.1.7
3
+ Version: 0.1.9
4
4
  Summary: Python library for creating a database of hardware components for manufacturing
5
5
  Home-page: https://github.com/alekssadowski95/OpenPartsLibrary
6
6
  Author: Aleksander Sadowski
@@ -130,6 +130,8 @@ Creating parts from a parts list in a Excel-spreadsheet (*.xlsx). Take note, tha
130
130
  ```python
131
131
  pl.create_parts_from_spreadsheet('C:/Users/Work/Documents/Github/OpenPartsLibrary/openpartslibrary/sample/parts_data_sample.xlsx')
132
132
  ```
133
+ ## Database structure
134
+ <img src="./openpartslibrary/images/Database-structure-openpartslibrary.png" width="100%" alt="OpenPartsLibrary database structure"></img>
133
135
 
134
136
  ## Part schema
135
137
  This table outlines the `Part` properties used in the OpenPartsLibrary.
@@ -7,5 +7,6 @@ OpenPartsLibrary.egg-info/dependency_links.txt
7
7
  OpenPartsLibrary.egg-info/requires.txt
8
8
  OpenPartsLibrary.egg-info/top_level.txt
9
9
  openpartslibrary/__init__.py
10
+ openpartslibrary/cli.py
10
11
  openpartslibrary/db.py
11
12
  openpartslibrary/models.py
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: OpenPartsLibrary
3
- Version: 0.1.7
3
+ Version: 0.1.9
4
4
  Summary: Python library for creating a database of hardware components for manufacturing
5
5
  Home-page: https://github.com/alekssadowski95/OpenPartsLibrary
6
6
  Author: Aleksander Sadowski
@@ -130,6 +130,8 @@ Creating parts from a parts list in a Excel-spreadsheet (*.xlsx). Take note, tha
130
130
  ```python
131
131
  pl.create_parts_from_spreadsheet('C:/Users/Work/Documents/Github/OpenPartsLibrary/openpartslibrary/sample/parts_data_sample.xlsx')
132
132
  ```
133
+ ## Database structure
134
+ <img src="./openpartslibrary/images/Database-structure-openpartslibrary.png" width="100%" alt="OpenPartsLibrary database structure"></img>
133
135
 
134
136
  ## Part schema
135
137
  This table outlines the `Part` properties used in the OpenPartsLibrary.
@@ -101,6 +101,8 @@ Creating parts from a parts list in a Excel-spreadsheet (*.xlsx). Take note, tha
101
101
  ```python
102
102
  pl.create_parts_from_spreadsheet('C:/Users/Work/Documents/Github/OpenPartsLibrary/openpartslibrary/sample/parts_data_sample.xlsx')
103
103
  ```
104
+ ## Database structure
105
+ <img src="./openpartslibrary/images/Database-structure-openpartslibrary.png" width="100%" alt="OpenPartsLibrary database structure"></img>
104
106
 
105
107
  ## Part schema
106
108
  This table outlines the `Part` properties used in the OpenPartsLibrary.
@@ -137,4 +139,4 @@ Credits:
137
139
  icon: <a href="https://www.flaticon.com/free-icons/database" title="database icons">Database icons created by Smashicons - Flaticon</a>
138
140
 
139
141
  ## How to Contribute
140
- This section helps in understanding how to contribute to the project.
142
+ This section helps in understanding how to contribute to the project.
@@ -0,0 +1,51 @@
1
+ class PartsLibraryCLI:
2
+ def __init__(self):
3
+ ''' CLI to be moved to its own object OpenPartsLibraryCLI in cli.py
4
+ '''
5
+ '''
6
+ command_history = []
7
+ while True:
8
+ os.system('cls')
9
+ print('************************************************************')
10
+ print('* OpenPartsLibrary *')
11
+ print('* Aleksander Sadowski, Nandana Gopala Krishnan (C) 2025 *')
12
+ print('************************************************************')
13
+ pl.display()
14
+ commands = 'add part', 'add supplier', 'modify part', 'modify supplier', 'remove part', 'remove supplier'
15
+ commands_str = ''
16
+ for command in commands:
17
+ commands_str = commands_str + '[' + str(command) + '] '
18
+ print('Commands: ' + commands_str)
19
+ print('Last commands:' + str([command for command in command_history][-5:]))
20
+ input_cmd = input('Enter command: ')
21
+ command_history.append(input_cmd)
22
+ if input_cmd in commands:
23
+ if input_cmd == 'add part':
24
+ pass
25
+ if input_cmd == 'add supplier':
26
+ pass
27
+ if input_cmd == 'modify part':
28
+ os.system('cls')
29
+ print('************************************************************')
30
+ print('* OpenPartsLibrary *')
31
+ print('* Aleksander Sadowski, Nandana Gopala Krishnan (C) 2025 *')
32
+ print('************************************************************')
33
+ pl.display_parts()
34
+ selected_part = int(input('Enter part id: '))
35
+ pass
36
+ if input_cmd == 'modify supplier':
37
+ os.system('cls')
38
+ print('************************************************************')
39
+ print('* OpenPartsLibrary *')
40
+ print('* Aleksander Sadowski, Nandana Gopala Krishnan (C) 2025 *')
41
+ print('************************************************************')
42
+ print()
43
+ pl.display_suppliers()
44
+ selected_part = int(input('Enter supplier id: '))
45
+ pass
46
+ if input_cmd == 'remove part':
47
+ pass
48
+ if input_cmd == 'remove supplier':
49
+ pass
50
+ '''
51
+ pass
@@ -0,0 +1,218 @@
1
+ from sqlalchemy import create_engine
2
+ from sqlalchemy.orm import sessionmaker
3
+
4
+ import pandas as pd
5
+
6
+ from datetime import datetime
7
+
8
+ from .models import Base, Part, Supplier, File, Component, ComponentComponent
9
+
10
+ import uuid
11
+
12
+ import os
13
+
14
+
15
+ class PartsLibrary:
16
+ def __init__(self):
17
+ import os
18
+ sqlite_path = os.path.join(os.path.dirname(__file__), 'data', 'parts.db')
19
+ print(sqlite_path)
20
+ self.engine = create_engine('sqlite:///' + sqlite_path)
21
+
22
+ Base.metadata.create_all(self.engine)
23
+
24
+ self.session_factory = sessionmaker(bind=self.engine)
25
+ self.session = self.session_factory()
26
+
27
+ def display(self):
28
+ # Print the components table to the terminal
29
+ component_component_table = pd.read_sql_table(table_name="component_component", con=self.engine)
30
+ print('ComponentComponent:')
31
+ print('===================')
32
+ print(component_component_table)
33
+ print('')
34
+
35
+ # Print the components table to the terminal
36
+ components_table = pd.read_sql_table(table_name="components", con=self.engine)
37
+ print('Components:')
38
+ print('===========')
39
+ print(components_table)
40
+ print('')
41
+
42
+ # Print the parts table to the terminal
43
+ part_table = pd.read_sql_table(table_name="parts", con=self.engine)
44
+ print('Parts:')
45
+ print('======')
46
+ print(part_table)
47
+ print('')
48
+
49
+ # Print the suppliers table to the terminal
50
+ supplier_table = pd.read_sql_table(table_name="suppliers", con=self.engine)
51
+ print('Suppliers:')
52
+ print('==========')
53
+ print(supplier_table)
54
+ print('')
55
+
56
+ # Print the files table to the terminal
57
+ files_table = pd.read_sql_table(table_name="files", con=self.engine)
58
+ print('Files:')
59
+ print('==========')
60
+ print(files_table)
61
+ print('')
62
+
63
+ def display_reduced(self):
64
+ # Print the parts table to the terminal in reduced form
65
+ pass
66
+
67
+ def display_parts(self):
68
+ # Print the parts table to the terminal
69
+ part_table = pd.read_sql_table(table_name="parts", con=self.engine)
70
+ print('Parts:')
71
+ print('======')
72
+ print(part_table)
73
+ print('')
74
+
75
+ def display_suppliers(self):
76
+ # Print the suppliers table to the terminal
77
+ supplier_table = pd.read_sql_table(table_name="suppliers", con=self.engine)
78
+ print('Suppliers:')
79
+ print('==========')
80
+ print(supplier_table)
81
+ print('')
82
+
83
+ def display_files(self):
84
+ # Print the files table to the terminal
85
+ files_table = pd.read_sql_table(table_name="files", con=self.engine)
86
+ print('Files:')
87
+ print('==========')
88
+ print(files_table)
89
+ print('')
90
+
91
+ def delete_all(self):
92
+ print('[ INFO ] Clearing the parts library.')
93
+ self.session.query(ComponentComponent).delete()
94
+ self.session.query(Component).delete()
95
+ self.session.query(Part).delete()
96
+ self.session.query(Supplier).delete()
97
+ self.session.query(File).delete()
98
+ self.session.commit()
99
+
100
+ directory_to_empty = os.path.join(os.path.dirname(__file__), 'data', 'files')
101
+
102
+ for filename in os.listdir(directory_to_empty):
103
+ filepath = os.path.join(directory_to_empty, filename)
104
+ if os.path.isfile(filepath) and filename != "README.md":
105
+ os.remove(filepath)
106
+ print(f"[ INFO ] Deleted: {filename}")
107
+
108
+ def total_value(self):
109
+ from decimal import Decimal
110
+ all_parts = self.session.query(Part).all()
111
+
112
+ total_value = Decimal(0.0)
113
+ for part in all_parts:
114
+ total_value = Decimal(total_value) + (Decimal(part.unit_price) * part.quantity)
115
+
116
+ return total_value
117
+
118
+ def create_parts_from_spreadsheet(self, file_path):
119
+ df = pd.read_excel(file_path)
120
+
121
+ parts = []
122
+ for _, row in df.iterrows():
123
+ part = Part(
124
+ uuid=row["uuid"],
125
+ number=row["number"],
126
+ name=row["name"],
127
+ description=row.get("description", "No description"),
128
+ revision=str(row.get("revision", "1")),
129
+ lifecycle_state=row.get("lifecycle_state", "In Work"),
130
+ owner=row.get("owner", "system"),
131
+ date_created=row.get("date_created", datetime.utcnow()),
132
+ date_modified=row.get("date_modified", datetime.utcnow()),
133
+ material=row.get("material"),
134
+ mass=row.get("mass"),
135
+ dimension_x=row.get("dimension_x"),
136
+ dimension_y=row.get("dimension_y"),
137
+ dimension_z=row.get("dimension_z"),
138
+ quantity=row.get("quantity", 0),
139
+ cad_reference=row.get("cad_reference"),
140
+ attached_documents_reference=row.get("attached_documents_reference"),
141
+ lead_time=row.get("lead_time"),
142
+ make_or_buy=row.get("make_or_buy"),
143
+ manufacturer_number=row.get("manufacturer_number"),
144
+ unit_price=row.get("unit_price"),
145
+ currency=row.get("currency")
146
+ )
147
+ parts.append(part)
148
+
149
+ self.session.add_all(parts)
150
+ self.session.commit()
151
+ print(f"Imported {len(parts)} parts successfully from {file_path}")
152
+
153
+ def create_suppliers_from_spreadsheet(self, file_path):
154
+ self.session.query(Supplier).delete()
155
+ self.session.commit()
156
+
157
+ df = pd.read_excel(file_path)
158
+
159
+ suppliers = []
160
+ for _, row in df.iterrows():
161
+ supplier = Supplier(
162
+ uuid=row.get("uuid", str(uuid.uuid4())),
163
+ name=row["name"],
164
+ description=row.get("description", "No description"),
165
+ street=row.get("street"),
166
+ city=row.get("city"),
167
+ postal_code=row.get("postal_code"),
168
+ house_number=row.get("house_number"),
169
+ country=row.get("country")
170
+ )
171
+ suppliers.append(supplier)
172
+
173
+ self.session.add_all(suppliers)
174
+ self.session.commit()
175
+ print(f"Imported {len(suppliers)} suppliers successfully from {file_path}")
176
+
177
+ def display_suppliers_table(self):
178
+ from tabulate import tabulate
179
+ import textwrap
180
+ query="SELECT * FROM suppliers"
181
+ suppliers_table = pd.read_sql_query(sql=query, con=self.engine)
182
+ suppliers_table["house_number"] = suppliers_table["house_number"].astype(str)
183
+ suppliers_table["postal_code"] = suppliers_table["postal_code"].astype(str)
184
+ pd.set_option('display.max_columns', 7)
185
+ pd.set_option('display.width', 200)
186
+ print(tabulate(suppliers_table, headers='keys', tablefmt='github'))
187
+
188
+ def add_sample_suppliers(self):
189
+ from .models import Supplier
190
+ siemens = Supplier(
191
+ uuid=str(uuid.uuid4()),
192
+ name="Siemens AG",
193
+ description="Siemens AG is a global powerhouse focusing on the areas of electrification, automation, and digitalization. One of the world's largest producers of energy-efficient, resource-saving technologies",
194
+ street="Werner-von-Siemens-Straße",
195
+ house_number="1",
196
+ postal_code="80333",
197
+ city="Munich",
198
+ country="Germany",
199
+ date_created=datetime.utcnow(),
200
+ date_modified=datetime.utcnow()
201
+ )
202
+
203
+ kuka = Supplier(
204
+ uuid=str(uuid.uuid4()),
205
+ name="KUKA AG",
206
+ description="The KUKA Group is an internationally active automation group with revenue of approximately EUR 3.7 billion and approximately 15,000 employees. As one of the world's leading providers of intelligent, resource-efficient automation solutions, KUKA offers industrial robots, autonomous mobile robots (AMR) including controllers, software, and cloud-based digital services, as well as fully networked production systems for various industries and markets, such as automotive with a focus on e-mobility and batteries, electronics, metal and plastics, consumer goods, food, e-commerce, retail, and healthcare",
207
+ street="Zugspitzstraße",
208
+ house_number="140",
209
+ postal_code="86165",
210
+ city="Augsburg",
211
+ country="Germany",
212
+ date_created=datetime.utcnow(),
213
+ date_modified=datetime.utcnow()
214
+ )
215
+ self.session.add(siemens)
216
+ self.session.add(kuka)
217
+ self.session.commit()
218
+ print("Added sample suppliers: Siemens AG and KUKA AG")
@@ -0,0 +1,153 @@
1
+ from sqlalchemy import Column, Integer, String, Float, DateTime, Numeric, Enum, ForeignKey, UniqueConstraint
2
+ from sqlalchemy.orm import DeclarativeBase, relationship, backref
3
+ from datetime import datetime
4
+
5
+
6
+ class Base(DeclarativeBase):
7
+ pass
8
+
9
+ class ComponentComponent(Base):
10
+ __tablename__ = 'component_component'
11
+
12
+ id = Column(Integer, primary_key=True)
13
+
14
+ parent_component_id = Column(Integer, ForeignKey("components.id"), nullable=False)
15
+ child_component_id = Column(Integer, ForeignKey("components.id"), nullable=False)
16
+
17
+ __table_args__ = (UniqueConstraint("parent_component_id", "child_component_id", name="uq_parent_child"),)
18
+
19
+ def __repr__(self):
20
+ return f"<ComponentComponent(id={self.id}, parent_component_id={self.parent_component_id}, child_component_id={self.child_component_id})>"
21
+
22
+ class Component(Base):
23
+ __tablename__ = 'components'
24
+
25
+ id = Column(Integer, primary_key=True)
26
+ uuid = Column(String(32), unique=True, nullable=False)
27
+ name = Column(String(200), nullable=False)
28
+
29
+ part = relationship('Part', back_populates='component', uselist=False)
30
+
31
+ # children: Components that this component is parent of
32
+ children = relationship(
33
+ "Component",
34
+ secondary="component_component",
35
+ primaryjoin=id == ComponentComponent.parent_component_id,
36
+ secondaryjoin=id == ComponentComponent.child_component_id,
37
+ backref=backref("parents", lazy="joined"),
38
+ lazy="joined",
39
+ )
40
+
41
+ class File(Base):
42
+ __tablename__ = 'files'
43
+
44
+ id = Column(Integer, primary_key=True)
45
+ uuid = Column(String(32), unique=True, nullable=False)
46
+ name = Column(String(200), nullable=False)
47
+ description = Column(String(1000))
48
+ date_created = Column(DateTime, default=datetime.utcnow)
49
+ date_modified = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
50
+
51
+ part_id = Column(ForeignKey('parts.id'))
52
+ part = relationship('Part', back_populates='cad_reference')
53
+
54
+
55
+ class Part(Base):
56
+ __tablename__ = 'parts'
57
+
58
+ id = Column(Integer, primary_key=True)
59
+ uuid = Column(String(32), unique=True, nullable=False)
60
+ number = Column(String(50), nullable=False)
61
+ name = Column(String(200), nullable=False)
62
+ description = Column(String(1000), default="No description")
63
+ revision = Column(String(10), default="1")
64
+ lifecycle_state = Column(String(50), default="In Work")
65
+ owner = Column(String(100), default="system")
66
+ date_created = Column(DateTime, default=datetime.utcnow)
67
+ date_modified = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
68
+ material = Column(String(100))
69
+ mass = Column(Float)
70
+ dimension_x = Column(Float)
71
+ dimension_y = Column(Float)
72
+ dimension_z = Column(Float)
73
+ quantity = Column(Integer, default=0)
74
+ attached_documents_reference = Column(String(200))
75
+ lead_time = Column(Integer)
76
+ make_or_buy = Column(Enum('make', 'buy', name='make_or_buy_enum'))
77
+ manufacturer_number = Column(String(100))
78
+ unit_price = Column(Numeric(10, 2))
79
+ currency = Column(String(3))
80
+
81
+ cad_reference = relationship('File', back_populates='part', uselist=False)
82
+
83
+ supplier_id = Column(ForeignKey('suppliers.id'))
84
+ supplier = relationship('Supplier', back_populates='parts')
85
+
86
+ component_id = Column(ForeignKey('components.id'))
87
+ component = relationship('Component', back_populates='part')
88
+
89
+ def __repr__(self):
90
+ return f"<Part(id={self.id}, number={self.number}, name={self.name})>"
91
+
92
+ def to_dict(self):
93
+ return {column.name: getattr(self, column.name) for column in self.__table__.columns}
94
+
95
+ class Supplier(Base):
96
+ __tablename__ = 'suppliers'
97
+
98
+ id = Column(Integer, primary_key=True)
99
+ uuid = Column(String(32), unique=True, nullable=False)
100
+ name = Column(String(200), nullable=False)
101
+ description = Column(String(1000), default="No description")
102
+ street = Column(String(200))
103
+ house_number = Column(String(20))
104
+ postal_code = Column(String(20))
105
+ city = Column(String(100))
106
+ country = Column(String(100))
107
+ date_created = Column(DateTime, default=datetime.utcnow)
108
+ date_modified = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
109
+
110
+ parts = relationship(Part)
111
+
112
+ def to_dict(self):
113
+ return {column.name: getattr(self, column.name) for column in self.__table__.columns}
114
+
115
+ class Adress(Base):
116
+ __tablename__ = 'adresses'
117
+
118
+ id = Column(Integer, primary_key=True)
119
+ uuid = Column(String(32), unique=True, nullable=False)
120
+ street = Column(String(200))
121
+ house_number = Column(String(20))
122
+ postal_code = Column(String(20))
123
+ city = Column(String(100))
124
+ country = Column(String(100))
125
+
126
+
127
+ '''
128
+ Relationship tables
129
+ '''
130
+
131
+ class PartSupplier(Base):
132
+ __tablename__ = 'part_supplier'
133
+
134
+ id = Column(Integer, primary_key=True)
135
+
136
+ class PartFile(Base):
137
+ __tablename__ = 'part_file'
138
+
139
+ id = Column(Integer, primary_key=True)
140
+
141
+ class SupplierAdress(Base):
142
+ __tablename__ = 'supplier_adress'
143
+
144
+ id = Column(Integer, primary_key=True)
145
+
146
+ class SupplierFile(Base):
147
+ __tablename__ = 'supplier_file'
148
+
149
+ id = Column(Integer, primary_key=True)
150
+
151
+
152
+
153
+
@@ -8,7 +8,7 @@ long_description = (this_directory / "README.md").read_text()
8
8
 
9
9
  setup(
10
10
  name='OpenPartsLibrary',
11
- version='0.1.7',
11
+ version='0.1.9',
12
12
  description='Python library for creating a database of hardware components for manufacturing',
13
13
  long_description=long_description,
14
14
  long_description_content_type='text/markdown',
@@ -1,87 +0,0 @@
1
- from sqlalchemy import create_engine
2
- from sqlalchemy.orm import sessionmaker
3
-
4
- import pandas as pd
5
-
6
- from datetime import datetime
7
-
8
- from .models import Base, Part
9
-
10
-
11
- class PartsLibrary:
12
- def __init__(self):
13
- import os
14
- sqlite_path = os.path.join(os.path.dirname(__file__), 'data', 'parts.db')
15
- print(sqlite_path)
16
- self.engine = create_engine('sqlite:///' + sqlite_path)
17
-
18
- Base.metadata.create_all(self.engine)
19
-
20
- self.session_factory = sessionmaker(bind=self.engine)
21
- self.session = self.session_factory()
22
-
23
- def display(self):
24
- part_table = pd.read_sql_table(table_name="parts", con=self.engine)
25
-
26
- pd.set_option('display.max_columns', 8)
27
- pd.set_option('display.width', 240)
28
-
29
- print(part_table)
30
-
31
- def display_reduced(self):
32
- part_table = pd.read_sql_table(table_name="parts", con=self.engine)
33
- reduced_part_table = part_table[["id", "number", "name", "quantity", "mass", "lead_time", "supplier", "unit_price", "currency"]]
34
- pd.set_option('display.max_columns', 9)
35
- pd.set_option('display.width', 200)
36
- print(reduced_part_table)
37
-
38
-
39
- def delete_all(self):
40
- self.session.query(Part).delete()
41
- self.session.commit()
42
-
43
- def create_parts_from_spreadsheet(self, file_path):
44
- df = pd.read_excel(file_path)
45
-
46
- parts = []
47
- for _, row in df.iterrows():
48
- part = Part(
49
- uuid=row["uuid"],
50
- number=row["number"],
51
- name=row["name"],
52
- description=row.get("description", "No description"),
53
- revision=str(row.get("revision", "1")),
54
- lifecycle_state=row.get("lifecycle_state", "In Work"),
55
- owner=row.get("owner", "system"),
56
- date_created=row.get("date_created", datetime.utcnow()),
57
- date_modified=row.get("date_modified", datetime.utcnow()),
58
- material=row.get("material"),
59
- mass=row.get("mass"),
60
- dimension_x=row.get("dimension_x"),
61
- dimension_y=row.get("dimension_y"),
62
- dimension_z=row.get("dimension_z"),
63
- quantity=row.get("quantity", 0),
64
- cad_reference=row.get("cad_reference"),
65
- attached_documents_reference=row.get("attached_documents_reference"),
66
- lead_time=row.get("lead_time"),
67
- make_or_buy=row.get("make_or_buy"),
68
- supplier=row.get("supplier"),
69
- manufacturer_number=row.get("manufacturer_number"),
70
- unit_price=row.get("unit_price"),
71
- currency=row.get("currency")
72
- )
73
- parts.append(part)
74
-
75
- self.session.add_all(parts)
76
- self.session.commit()
77
- print(f"Imported {len(parts)} parts successfully from {file_path}")
78
-
79
- def total_value(self):
80
- from decimal import Decimal
81
- all_parts = self.session.query(Part).all()
82
-
83
- total_value = Decimal(0.0)
84
- for part in all_parts:
85
- total_value = Decimal(total_value) + (Decimal(part.unit_price) * part.quantity)
86
-
87
- return total_value
@@ -1,71 +0,0 @@
1
- from sqlalchemy import Column, Integer, String, Float, DateTime, Numeric, Enum
2
- from sqlalchemy.orm import DeclarativeBase
3
- from datetime import datetime
4
-
5
- import uuid
6
-
7
- class Base(DeclarativeBase):
8
- pass
9
-
10
- class Part(Base):
11
- __tablename__ = 'parts'
12
-
13
- id = Column(Integer, primary_key=True)
14
- uuid = Column(String(32), unique=True, nullable=False, default=str(uuid.uuid4()))
15
- number = Column(String(50), nullable=False)
16
- name = Column(String(200), nullable=False)
17
- description = Column(String(1000), default="No description")
18
- revision = Column(String(10), default="1")
19
- lifecycle_state = Column(String(50), default="In Work")
20
- owner = Column(String(100), default="system")
21
- date_created = Column(DateTime, default=datetime.utcnow)
22
- date_modified = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
23
- material = Column(String(100))
24
- mass = Column(Float)
25
- dimension_x = Column(Float)
26
- dimension_y = Column(Float)
27
- dimension_z = Column(Float)
28
- quantity = Column(Integer, default=0)
29
- cad_reference = Column(String(200))
30
- attached_documents_reference = Column(String(200))
31
- lead_time = Column(Integer)
32
- make_or_buy = Column(Enum('make', 'buy', name='make_or_buy_enum'))
33
- supplier = Column(String(100))
34
- manufacturer_number = Column(String(100))
35
- unit_price = Column(Numeric(10, 2))
36
- currency = Column(String(3))
37
-
38
- def __repr__(self):
39
- return f"<Part(id={self.id}, number={self.number}, name={self.name})>"
40
-
41
- def to_dict(self):
42
- return {column.name: getattr(self, column.name) for column in self.__table__.columns}
43
-
44
-
45
- class Supplier(Base):
46
- __tablename__ = 'suppliers'
47
-
48
- id = Column(Integer, primary_key=True)
49
- uuid = Column(String(32), unique=True, nullable=False)
50
- name = Column(String(200), nullable=False)
51
- description = Column(String(1000))
52
- date_created = Column(DateTime, default=datetime.utcnow)
53
- date_modified = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
54
-
55
- class File(Base):
56
- __tablename__ = 'files'
57
-
58
- id = Column(Integer, primary_key=True)
59
- uuid = Column(String(32), unique=True, nullable=False)
60
- name = Column(String(200), nullable=False)
61
- description = Column(String(1000))
62
- date_created = Column(DateTime, default=datetime.utcnow)
63
- date_modified = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
64
-
65
- class NumberRange(Base):
66
- __tablename__ = 'number_ranges'
67
-
68
- id = Column(Integer, primary_key=True)
69
- name = Column(String(200), nullable=False)
70
- description = Column(String(1000))
71
- date_created = Column(DateTime, default=datetime.utcnow)