mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
More refactoring
This commit is contained in:
parent
c533f59405
commit
e049ca1a85
@ -362,6 +362,17 @@ class AjaxCreateView(AjaxMixin, CreateView):
|
||||
form = self.get_form()
|
||||
return self.renderJsonResponse(request, form)
|
||||
|
||||
def do_save(self, form):
|
||||
"""
|
||||
Method for actually saving the form to the database.
|
||||
Default implementation is very simple,
|
||||
but can be overridden if required.
|
||||
"""
|
||||
|
||||
self.object = form.save()
|
||||
|
||||
return self.object
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
""" Responds to form POST. Validates POST data and returns status info.
|
||||
|
||||
@ -385,13 +396,17 @@ class AjaxCreateView(AjaxMixin, CreateView):
|
||||
'form_valid': valid
|
||||
}
|
||||
|
||||
# Add in any extra class data
|
||||
for value, key in enumerate(self.get_data()):
|
||||
data[key] = value
|
||||
|
||||
if valid:
|
||||
|
||||
# Perform (optional) pre-save step
|
||||
self.pre_save(None, self.form)
|
||||
|
||||
# Save the object to the database
|
||||
self.object = self.form.save()
|
||||
self.do_save(self.form)
|
||||
|
||||
# Perform (optional) post-save step
|
||||
self.post_save(self.object, self.form)
|
||||
@ -425,6 +440,17 @@ class AjaxUpdateView(AjaxMixin, UpdateView):
|
||||
|
||||
return self.renderJsonResponse(request, self.get_form(), context=self.get_context_data())
|
||||
|
||||
def do_save(self, form):
|
||||
"""
|
||||
Method for updating the object in the database.
|
||||
Default implementation is very simple,
|
||||
but can be overridden if required.
|
||||
"""
|
||||
|
||||
self.object = form.save()
|
||||
|
||||
return self.object
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
""" Respond to POST request.
|
||||
|
||||
@ -453,13 +479,17 @@ class AjaxUpdateView(AjaxMixin, UpdateView):
|
||||
'form_valid': valid
|
||||
}
|
||||
|
||||
# Add in any extra class data
|
||||
for value, key in enumerate(self.get_data()):
|
||||
data[key] = value
|
||||
|
||||
if valid:
|
||||
|
||||
# Perform (optional) pre-save step
|
||||
self.pre_save(self.object, form)
|
||||
|
||||
# Save the updated objec to the database
|
||||
obj = form.save()
|
||||
obj = self.do_save(form)
|
||||
|
||||
# Perform (optional) post-save step
|
||||
self.post_save(obj, form)
|
||||
|
@ -60,30 +60,25 @@ class BuildCancel(AjaxUpdateView):
|
||||
form_class = forms.CancelBuildForm
|
||||
role_required = 'build.change'
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
""" Handle POST request. Mark the build status as CANCELLED """
|
||||
def validate(self, build, form, **kwargs):
|
||||
|
||||
build = self.get_object()
|
||||
confirm = str2bool(form.cleaned_data.get('confirm_cancel', False))
|
||||
|
||||
form = self.get_form()
|
||||
|
||||
valid = form.is_valid()
|
||||
|
||||
confirm = str2bool(request.POST.get('confirm_cancel', False))
|
||||
|
||||
if confirm:
|
||||
build.cancelBuild(request.user)
|
||||
else:
|
||||
if not confirm:
|
||||
form.add_error('confirm_cancel', _('Confirm build cancellation'))
|
||||
valid = False
|
||||
|
||||
data = {
|
||||
'form_valid': valid,
|
||||
def post_save(self, build, form, **kwargs):
|
||||
"""
|
||||
Cancel the build.
|
||||
"""
|
||||
|
||||
build.cancelBuild(self.request.user)
|
||||
|
||||
def get_data(self):
|
||||
return {
|
||||
'danger': _('Build was cancelled')
|
||||
}
|
||||
|
||||
return self.renderJsonResponse(request, form, data=data)
|
||||
|
||||
|
||||
class BuildAutoAllocate(AjaxUpdateView):
|
||||
""" View to auto-allocate parts for a build.
|
||||
|
@ -209,6 +209,7 @@ class PurchaseOrder(Order):
|
||||
|
||||
line.save()
|
||||
|
||||
@transaction.atomic
|
||||
def place_order(self):
|
||||
""" Marks the PurchaseOrder as PLACED. Order must be currently PENDING. """
|
||||
|
||||
@ -217,6 +218,7 @@ class PurchaseOrder(Order):
|
||||
self.issue_date = datetime.now().date()
|
||||
self.save()
|
||||
|
||||
@transaction.atomic
|
||||
def complete_order(self):
|
||||
""" Marks the PurchaseOrder as COMPLETE. Order must be currently PLACED. """
|
||||
|
||||
@ -225,10 +227,16 @@ class PurchaseOrder(Order):
|
||||
self.complete_date = datetime.now().date()
|
||||
self.save()
|
||||
|
||||
def can_cancel(self):
|
||||
return self.status not in [
|
||||
PurchaseOrderStatus.PLACED,
|
||||
PurchaseOrderStatus.PENDING
|
||||
]
|
||||
|
||||
def cancel_order(self):
|
||||
""" Marks the PurchaseOrder as CANCELLED. """
|
||||
|
||||
if self.status in [PurchaseOrderStatus.PLACED, PurchaseOrderStatus.PENDING]:
|
||||
if self.can_cancel():
|
||||
self.status = PurchaseOrderStatus.CANCELLED
|
||||
self.save()
|
||||
|
||||
@ -377,6 +385,16 @@ class SalesOrder(Order):
|
||||
|
||||
return True
|
||||
|
||||
def can_cancel(self):
|
||||
"""
|
||||
Return True if this order can be cancelled
|
||||
"""
|
||||
|
||||
if not self.status == SalesOrderStatus.PENDING:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
@transaction.atomic
|
||||
def cancel_order(self):
|
||||
"""
|
||||
@ -386,7 +404,7 @@ class SalesOrder(Order):
|
||||
- Delete any StockItems which have been allocated
|
||||
"""
|
||||
|
||||
if not self.status == SalesOrderStatus.PENDING:
|
||||
if not self.can_cancel():
|
||||
return False
|
||||
|
||||
self.status = SalesOrderStatus.CANCELLED
|
||||
|
@ -404,29 +404,19 @@ class PurchaseOrderCancel(AjaxUpdateView):
|
||||
form_class = order_forms.CancelPurchaseOrderForm
|
||||
role_required = 'purchase_order.change'
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
""" Mark the PO as 'CANCELLED' """
|
||||
|
||||
order = self.get_object()
|
||||
form = self.get_form()
|
||||
|
||||
confirm = str2bool(request.POST.get('confirm', False))
|
||||
|
||||
valid = False
|
||||
def validate(self, order, form, **kwargs):
|
||||
|
||||
confirm = str2bool(form.cleaned_data.get('confirm', False))
|
||||
|
||||
if not confirm:
|
||||
form.add_error('confirm', _('Confirm order cancellation'))
|
||||
else:
|
||||
valid = True
|
||||
|
||||
data = {
|
||||
'form_valid': valid
|
||||
}
|
||||
if not order.can_cancel():
|
||||
form.add_error(None, _('Order cannot be cancelled'))
|
||||
|
||||
if valid:
|
||||
order.cancel_order()
|
||||
def post_save(self, order, form, **kwargs):
|
||||
|
||||
return self.renderJsonResponse(request, form, data)
|
||||
order.cancel_order()
|
||||
|
||||
|
||||
class SalesOrderCancel(AjaxUpdateView):
|
||||
@ -438,30 +428,19 @@ class SalesOrderCancel(AjaxUpdateView):
|
||||
form_class = order_forms.CancelSalesOrderForm
|
||||
role_required = 'sales_order.change'
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
def validate(self, order, form, **kwargs):
|
||||
|
||||
order = self.get_object()
|
||||
form = self.get_form()
|
||||
|
||||
confirm = str2bool(request.POST.get('confirm', False))
|
||||
|
||||
valid = False
|
||||
confirm = str2bool(form.cleaned_data.get('confirm', False))
|
||||
|
||||
if not confirm:
|
||||
form.add_error('confirm', _('Confirm order cancellation'))
|
||||
else:
|
||||
valid = True
|
||||
|
||||
if valid:
|
||||
if not order.cancel_order():
|
||||
form.add_error(None, _('Could not cancel order'))
|
||||
valid = False
|
||||
if not order.can_cancel():
|
||||
form.add_error(None, _('Order cannot be cancelled'))
|
||||
|
||||
data = {
|
||||
'form_valid': valid,
|
||||
}
|
||||
def post_save(self, order, form, **kwargs):
|
||||
|
||||
return self.renderJsonResponse(request, form, data)
|
||||
order.cancel_order()
|
||||
|
||||
|
||||
class PurchaseOrderIssue(AjaxUpdateView):
|
||||
@ -473,30 +452,22 @@ class PurchaseOrderIssue(AjaxUpdateView):
|
||||
form_class = order_forms.IssuePurchaseOrderForm
|
||||
role_required = 'purchase_order.change'
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
""" Mark the purchase order as 'PLACED' """
|
||||
def validate(self, order, form, **kwargs):
|
||||
|
||||
order = self.get_object()
|
||||
form = self.get_form()
|
||||
|
||||
confirm = str2bool(request.POST.get('confirm', False))
|
||||
|
||||
valid = False
|
||||
confirm = str2bool(form.cleaned_data.get('confirm', False))
|
||||
|
||||
if not confirm:
|
||||
form.add_error('confirm', _('Confirm order placement'))
|
||||
else:
|
||||
valid = True
|
||||
|
||||
data = {
|
||||
'form_valid': valid,
|
||||
def post_save(self, order, form, **kwargs):
|
||||
|
||||
order.place_order()
|
||||
|
||||
def get_data(self):
|
||||
return {
|
||||
'success': _('Purchase order issued')
|
||||
}
|
||||
|
||||
if valid:
|
||||
order.place_order()
|
||||
|
||||
return self.renderJsonResponse(request, form, data)
|
||||
|
||||
|
||||
class PurchaseOrderComplete(AjaxUpdateView):
|
||||
""" View for marking a PurchaseOrder as complete.
|
||||
@ -517,24 +488,22 @@ class PurchaseOrderComplete(AjaxUpdateView):
|
||||
|
||||
return ctx
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
def validate(self, order, form, **kwargs):
|
||||
|
||||
confirm = str2bool(request.POST.get('confirm', False))
|
||||
confirm = str2bool(form.cleaned_data.get('confirm', False))
|
||||
|
||||
if confirm:
|
||||
po = self.get_object()
|
||||
po.status = PurchaseOrderStatus.COMPLETE
|
||||
po.save()
|
||||
if not confirm:
|
||||
form.add_error('confirm', _('Confirm order completion'))
|
||||
|
||||
data = {
|
||||
'form_valid': confirm
|
||||
def post_save(self, order, form, **kwargs):
|
||||
|
||||
order.complete_order()
|
||||
|
||||
def get_data(self):
|
||||
return {
|
||||
'success': _('Purchase order completed')
|
||||
}
|
||||
|
||||
form = self.get_form()
|
||||
|
||||
return self.renderJsonResponse(request, form, data)
|
||||
|
||||
|
||||
class SalesOrderShip(AjaxUpdateView):
|
||||
""" View for 'shipping' a SalesOrder """
|
||||
form_class = order_forms.ShipSalesOrderForm
|
||||
@ -1117,52 +1086,21 @@ class POLineItemCreate(AjaxCreateView):
|
||||
ajax_form_title = _('Add Line Item')
|
||||
role_required = 'purchase_order.add'
|
||||
|
||||
def post(self, request, *arg, **kwargs):
|
||||
def validate(self, item, form, **kwargs):
|
||||
|
||||
self.request = request
|
||||
order = form.cleaned_data.get('order', None)
|
||||
|
||||
form = self.get_form()
|
||||
part = form.cleaned_data.get('part', None)
|
||||
|
||||
valid = form.is_valid()
|
||||
if not part:
|
||||
form.add_error('part', _('Supplier part must be specified'))
|
||||
|
||||
# Extract the SupplierPart ID from the form
|
||||
part_id = form['part'].value()
|
||||
|
||||
# Extract the Order ID from the form
|
||||
order_id = form['order'].value()
|
||||
|
||||
try:
|
||||
order = PurchaseOrder.objects.get(id=order_id)
|
||||
except (ValueError, PurchaseOrder.DoesNotExist):
|
||||
order = None
|
||||
form.add_error('order', _('Invalid Purchase Order'))
|
||||
valid = False
|
||||
|
||||
try:
|
||||
sp = SupplierPart.objects.get(id=part_id)
|
||||
|
||||
if order is not None:
|
||||
if not sp.supplier == order.supplier:
|
||||
form.add_error('part', _('Supplier must match for Part and Order'))
|
||||
valid = False
|
||||
|
||||
except (SupplierPart.DoesNotExist, ValueError):
|
||||
valid = False
|
||||
form.add_error('part', _('Invalid SupplierPart selection'))
|
||||
|
||||
data = {
|
||||
'form_valid': valid,
|
||||
}
|
||||
|
||||
if valid:
|
||||
self.object = form.save()
|
||||
|
||||
data['pk'] = self.object.pk
|
||||
data['text'] = str(self.object)
|
||||
else:
|
||||
self.object = None
|
||||
|
||||
return self.renderJsonResponse(request, form, data,)
|
||||
if part and order:
|
||||
if not part.supplier == order.supplier:
|
||||
form.add_error(
|
||||
'part',
|
||||
_('Supplier must match for Part and Order')
|
||||
)
|
||||
|
||||
def get_form(self):
|
||||
""" Limit choice options based on the selected order, etc
|
||||
|
@ -1133,6 +1133,31 @@ class Part(MPTTModel):
|
||||
|
||||
bom_item.save()
|
||||
|
||||
@transaction.atomic
|
||||
def copy_parameters_from(self, other, **kwargs):
|
||||
|
||||
clear = kwargs.get('clear', True)
|
||||
|
||||
if clear:
|
||||
self.get_parameters().delete()
|
||||
|
||||
for parameter in other.get_parameters.all():
|
||||
|
||||
# If this part already has a parameter pointing to the same template,
|
||||
# delete that parameter from this part first!
|
||||
|
||||
try:
|
||||
existing = PartParameter.objects.get(part=self, template=parameter.template)
|
||||
existing.delete()
|
||||
except (PartParameter.DoesNotExist):
|
||||
pass
|
||||
|
||||
parameter.part = self
|
||||
parameter.pk = None
|
||||
|
||||
parameter.save()
|
||||
|
||||
@transaction.atomic
|
||||
def deepCopy(self, other, **kwargs):
|
||||
""" Duplicates non-field data from another part.
|
||||
Does not alter the normal fields of this part,
|
||||
@ -1156,15 +1181,8 @@ class Part(MPTTModel):
|
||||
|
||||
# Copy the parameters data
|
||||
if kwargs.get('parameters', True):
|
||||
# Get template part parameters
|
||||
parameters = other.get_parameters()
|
||||
# Copy template part parameters to new variant part
|
||||
for parameter in parameters:
|
||||
PartParameter.create(part=self,
|
||||
template=parameter.template,
|
||||
data=parameter.data,
|
||||
save=True)
|
||||
|
||||
self.copy_parameters_from(other)
|
||||
|
||||
# Copy the fields that aren't available in the duplicate form
|
||||
self.salable = other.salable
|
||||
self.assembly = other.assembly
|
||||
|
@ -371,6 +371,8 @@ class MakePartVariant(AjaxCreateView):
|
||||
initials = model_to_dict(part_template)
|
||||
initials['is_template'] = False
|
||||
initials['variant_of'] = part_template
|
||||
initials['bom_copy'] = InvenTreeSetting.get_setting('PART_COPY_BOM')
|
||||
initials['parameters_copy'] = InvenTreeSetting.get_seting('PART_COPY_PARAMETERS')
|
||||
|
||||
return initials
|
||||
|
||||
@ -906,23 +908,21 @@ class BomValidate(AjaxUpdateView):
|
||||
|
||||
return self.renderJsonResponse(request, form, context=self.get_context())
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
def validate(self, part, form, **kwargs):
|
||||
|
||||
form = self.get_form()
|
||||
part = self.get_object()
|
||||
confirm = str2bool(form.cleaned_data.get('validate', False))
|
||||
|
||||
confirmed = str2bool(request.POST.get('validate', False))
|
||||
|
||||
if confirmed:
|
||||
part.validate_bom(request.user)
|
||||
else:
|
||||
if not confirm:
|
||||
form.add_error('validate', _('Confirm that the BOM is valid'))
|
||||
|
||||
data = {
|
||||
'form_valid': confirmed
|
||||
}
|
||||
def post_save(self, part, form, **kwargs):
|
||||
|
||||
return self.renderJsonResponse(request, form, data, context=self.get_context())
|
||||
part.validate_bom(self.request.user)
|
||||
|
||||
def get_data(self):
|
||||
return {
|
||||
'success': _('Validated Bill of Materials')
|
||||
}
|
||||
|
||||
|
||||
class BomUpload(InvenTreeRoleMixin, FormView):
|
||||
|
@ -1126,6 +1126,20 @@ class StockItem(MPTTModel):
|
||||
|
||||
return s
|
||||
|
||||
@transaction.atomic
|
||||
def clear_test_results(self, **kwargs):
|
||||
"""
|
||||
Remove all test results
|
||||
"""
|
||||
|
||||
# All test results
|
||||
results = self.test_results.all()
|
||||
|
||||
# TODO - Perhaps some filtering options supplied by kwargs?
|
||||
|
||||
results.delete()
|
||||
|
||||
|
||||
def getTestResults(self, test=None, result=None, user=None):
|
||||
"""
|
||||
Return all test results associated with this StockItem.
|
||||
|
@ -245,32 +245,28 @@ class StockItemAssignToCustomer(AjaxUpdateView):
|
||||
form_class = StockForms.AssignStockItemToCustomerForm
|
||||
role_required = 'stock.change'
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
def validate(self, item, form, **kwargs):
|
||||
|
||||
customer = request.POST.get('customer', None)
|
||||
customer = form.cleaned_data.get('customer', None)
|
||||
|
||||
if not customer:
|
||||
form.add_error('customer', _('Customer must be specified'))
|
||||
|
||||
def post_save(self, item, form, **kwargs):
|
||||
"""
|
||||
Assign the stock item to the customer.
|
||||
"""
|
||||
|
||||
customer = form.cleaned_data.get('customer', None)
|
||||
|
||||
if customer:
|
||||
try:
|
||||
customer = Company.objects.get(pk=customer)
|
||||
except (ValueError, Company.DoesNotExist):
|
||||
customer = None
|
||||
|
||||
if customer is not None:
|
||||
stock_item = self.get_object()
|
||||
|
||||
item = stock_item.allocateToCustomer(
|
||||
item = item.allocateToCustomer(
|
||||
customer,
|
||||
user=request.user
|
||||
user=self.request.user
|
||||
)
|
||||
|
||||
item.clearAllocations()
|
||||
|
||||
data = {
|
||||
'form_valid': True,
|
||||
}
|
||||
|
||||
return self.renderJsonResponse(request, self.get_form(), data)
|
||||
|
||||
|
||||
class StockItemReturnToStock(AjaxUpdateView):
|
||||
"""
|
||||
@ -283,30 +279,25 @@ class StockItemReturnToStock(AjaxUpdateView):
|
||||
form_class = StockForms.ReturnStockItemForm
|
||||
role_required = 'stock.change'
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
def validate(self, item, form, **kwargs):
|
||||
|
||||
location = request.POST.get('location', None)
|
||||
location = form.cleaned_data.get('location', None)
|
||||
|
||||
if not location:
|
||||
form.add_error('location', _('Specify a valid location'))
|
||||
|
||||
def post_save(self, item, form, **kwargs):
|
||||
|
||||
location = form.cleaned_data.get('location', None)
|
||||
|
||||
if location:
|
||||
try:
|
||||
location = StockLocation.objects.get(pk=location)
|
||||
except (ValueError, StockLocation.DoesNotExist):
|
||||
location = None
|
||||
item.returnFromCustomer(location, self.request.user)
|
||||
|
||||
if location:
|
||||
stock_item = self.get_object()
|
||||
|
||||
stock_item.returnFromCustomer(location, request.user)
|
||||
else:
|
||||
raise ValidationError({'location': _("Specify a valid location")})
|
||||
|
||||
data = {
|
||||
'form_valid': True,
|
||||
'success': _("Stock item returned from customer")
|
||||
def get_data(self):
|
||||
return {
|
||||
'success': _('Stock item returned from customer')
|
||||
}
|
||||
|
||||
return self.renderJsonResponse(request, self.get_form(), data)
|
||||
|
||||
|
||||
class StockItemSelectLabels(AjaxView):
|
||||
"""
|
||||
|
Loading…
Reference in New Issue
Block a user