Files
mold_cost_online_tool/app/forms/quotation.py
T

193 lines
8.0 KiB
Python

from flask_wtf import FlaskForm
from wtforms import (
StringField,
SelectField,
DateField,
SubmitField
)
from wtforms.validators import (
DataRequired,
Length,
ValidationError
)
def validate_tooling_id_format(form, field):
"""Custom validator to ensure tooling_id is exactly 5 digits"""
if not field.data.isdigit() or len(field.data) != 5:
raise ValidationError('Tooling ID must be exactly 5 digits')
class QuotationForm(FlaskForm):
# Factory Information
mold_shop_name = StringField('Mold Shop Name', validators=[DataRequired()])
mold_shop_country = SelectField('Mold Shop Country', validators=[DataRequired()], choices=[
('', 'Select Country'),
('China', 'China'),
('Vietnam', 'Vietnam'),
('Indonesia', 'Indonesia')
])
t1_shoe_factory_name = StringField('T1 Shoe Factory Name', validators=[DataRequired()])
t1_shoe_factory_country = SelectField('T1 Shoe Factory Country', validators=[DataRequired()], choices=[
('', 'Select Country'),
('China', 'China'),
('Vietnam', 'Vietnam'),
('Indonesia', 'Indonesia')
])
t2_component_factory_name = StringField('T2 Component Factory Name', validators=[DataRequired()])
t2_component_factory_country = SelectField('T2 Component Factory Country', validators=[DataRequired()], choices=[
('', 'Select Country'),
('China', 'China'),
('Vietnam', 'Vietnam'),
('Indonesia', 'Indonesia')
])
# Mold Information
model_name = StringField('Model Name', validators=[DataRequired()])
tooling_id = StringField('Tooling ID', validators=[DataRequired(), Length(min=5, max=5), validate_tooling_id_format], id='tooling_id')
season = StringField('Season', validators=[DataRequired()])
# Define stage-type mapping
STAGE_TYPE_MAPPING = {
'CR0': ['Sample'],
'CR1': ['Sample'],
'CR2': ['Sample'],
'SMS': ['A Set'],
'commercialization': ['A Set'],
'production': ['Additional']
}
# Define the mapping of main types to sub-types
MOLD_TYPE_MAPPING = {
'Rubber': ['Flat Outsole', 'Cupsole', 'Rubber Sole'],
'CMEVA': ['2 Plates Mold', '3 Plates Mold', '2 Plates with in-mold channel', 'Breathable + in-mold channel'],
'IMEVA': ['2 Plates Mold', '3 Plates Mold'],
'Sandal': ['Sandal with Upper Bandage', '2 Plate without Upper Bandage'],
'Co-shot mold': ['Co-shot mold', 'Foaming mold'],
'PU': ['2 Plates Mold', '3 Plates Mold']
}
# Define the mapping of sub-types to their specific options
MOLD_SPECIFIC_TYPE_OPTIONS = {
'Flat Outsole': ['Flat', 'Flat with Top/Heel Tip'],
'Cupsole': ['Top PL', 'Visible PL'],
'Rubber Sole': ['Top PL', 'Short PL (Heel/Forefoot)', 'Visible PL', 'Wave PL']
}
mold_main_type = SelectField('Mold Main Type', validators=[DataRequired()], choices=[
('', 'Select Main Type'),
('Rubber', 'Rubber'),
('CMEVA', 'CMEVA'),
('IMEVA', 'IMEVA'),
('Sandal', 'Sandal'),
('Co-shot mold', 'Co-shot mold'),
('PU', 'PU')
], id='mold_main_type')
mold_sub_type = SelectField('Mold Sub Type', validators=[DataRequired()], choices=[
('', 'Select Sub Type')
], id='mold_sub_type')
mold_specific_type = SelectField('Mold Specific Type', validators=[], choices=[
('', 'Select Specific Type')
], id='mold_specific_type', coerce=str, default='')
stage = SelectField('Stage', validators=[DataRequired()], choices=[
('', 'Select Stage'),
('CR0', 'CR0'),
('CR1', 'CR1'),
('CR2', 'CR2'),
('SMS', 'SMS'),
('commercialization', 'Commercialization'),
('production', 'Production')
], id='stage')
type = SelectField('Type', validators=[DataRequired()], choices=[
('', 'Select Type'),
('Sample', 'Sample'),
('A Set', 'A Set'),
('Additional', 'Additional')
], id='type')
# Dates and Approvals
issue_date = DateField('Issue Date', validators=[DataRequired()])
approved_by_mold_shop = StringField('Approved by (Mold Shop Representative)', validators=[DataRequired()])
approved_by_t1_tooling = StringField('Approved by (T1 Tooling Representative)', validators=[DataRequired()])
approved_by_lo_tooling = StringField('Approved by (LO Tooling)', validators=[DataRequired()])
# Mold Cost
sliders_count = SelectField('Number of Sliders', validators=[DataRequired()], choices=[
('', 'Select Number of Sliders'),
('0', '0'),
('1', '1'),
('2', '2'),
('3', '3'),
('4', '4')
])
cavity_count = SelectField('Number of Cavities', validators=[DataRequired()], choices=[
('', 'Select Number of Pairs'),
('0.5', '0.5 pair'),
('1', '1 pair'),
('1.5', '1.5 pair'),
('2', '2 pair'),
('2.5', '2.5 pair'),
('3', '3 pair')
])
digital_texture_type = SelectField('Digital Texture', validators=[DataRequired()], choices=[
('', 'Select Texture Type'),
('adidas_digital', 'adidas digital texture'),
('customized texture', 'customized texture'),
('laser', 'laser texture')
])
complexity_high_sidewall = SelectField('High Sidewall >60mm', validators=[DataRequired()], choices=[('no', 'No'), ('yes', 'Yes')])
submit = SubmitField('Calculate')
def __init__(self, *args, **kwargs):
super(QuotationForm, self).__init__(*args, **kwargs)
# Set initial choices for mold_sub_type based on default mold_main_type
if self.mold_main_type.data in self.MOLD_TYPE_MAPPING:
self.mold_sub_type.choices = [('', 'Select Sub Type')] + [(x, x) for x in self.MOLD_TYPE_MAPPING[self.mold_main_type.data]]
def validate_mold_sub_type(self, field):
main_type = self.mold_main_type.data
print(f"Validating sub_type: {field.data} for main_type: {main_type}")
if main_type and main_type in self.MOLD_TYPE_MAPPING:
valid_sub_types = self.MOLD_TYPE_MAPPING[main_type]
print(f"Valid sub_types for {main_type}: {valid_sub_types}")
if field.data not in valid_sub_types and field.data != '':
print(f"Invalid sub_type: {field.data}. Valid types: {valid_sub_types}")
raise ValidationError('Invalid sub-type for selected main type')
def validate_mold_specific_type(self, field):
"""Validate that the selected specific type is valid for the selected sub type."""
sub_type = self.mold_sub_type.data
if not sub_type:
field.data = ''
return
# Get valid specific types for the selected sub type
valid_specific_types = self.MOLD_SPECIFIC_TYPE_OPTIONS.get(sub_type, [])
# If there are no specific types for this sub-type, the field should be empty
if not valid_specific_types:
field.data = '' # Always clear the field if it shouldn't have a value
return
# If there are specific types, validate the selection
if field.data is None or field.data == '':
raise ValidationError(f'Specific type is required for {sub_type}')
if field.data not in valid_specific_types:
raise ValidationError(f'Invalid specific type for {sub_type}. Valid options are: {", ".join(valid_specific_types)}')
def validate_type(self, field):
stage = self.stage.data
print(f"Validating type: {field.data} for stage: {stage}")
if stage and stage in self.STAGE_TYPE_MAPPING:
valid_types = self.STAGE_TYPE_MAPPING[stage]
print(f"Valid types for {stage}: {valid_types}")
if field.data not in valid_types and field.data != '':
print(f"Invalid type: {field.data}")
raise ValidationError(f'Invalid type for {stage} stage. Allowed types: {", ".join(valid_types)}')
elif field.data != '':
raise ValidationError('Please select a stage first')
def validate_tooling_id(self, field):
validate_tooling_id_format(self, field)