__author__ = 'tanshu' from decimal import Decimal, InvalidOperation from summer.models import session_scope from summer.models.validation_exception import ValidationError from summer.models.master import Product def save_product(json): name = json['Name'].strip() if name == '': raise ValidationError('Name cannot be blank') units = json['Units'].strip() product_group = json['ProductGroup'] if product_group is None: raise ValidationError('Please choose a product group') product_group_id = product_group['ProductGroupID'] try: price = Decimal(json['Price']) if price < 0: raise ValidationError("Price must be a decimal >= 0") except (ValueError, InvalidOperation): raise ValidationError("Price must be a decimal >= 0") has_happy_hour = json['HasHappyHour'] service_tax = json['ServiceTax'] if service_tax is None: raise ValidationError('Please choose a service tax') service_tax_id = service_tax['TaxID'] vat = json['Vat'] if vat is None: raise ValidationError('Please choose vat') vat_id = vat['TaxID'] try: service_charge = Decimal(json['ServiceCharge']) if service_charge < 0: raise ValidationError("Service Charge must be a decimal >= 0") except (ValueError, InvalidOperation): raise ValidationError("Service Charge must be a decimal >= 0") sc_taxable = json['ScTaxable'] is_active = json['IsActive'] try: sort_order = Decimal(json['SortOrder']) if sort_order < 0: raise ValidationError("Sort Order must be a decimal >= 0") except (ValueError, InvalidOperation): raise ValidationError("Sort Order must be a decimal >= 0") item = Product(name, units, product_group_id, price, has_happy_hour, service_tax_id, vat_id, service_charge, sc_taxable, is_active, sort_order) with session_scope() as DBSession: DBSession.add(item) return product_info(item.id) def update_product(json): with session_scope() as DBSession: item = Product.by_id(json['ProductID'], session=DBSession) if item.is_fixture: raise ValidationError("{0} is a fixture and cannot be edited or deleted.".format(item.full_name)) item.name = json['Name'].strip() item.units = json['Units'].strip() item.product_group_id = json['ProductGroup']['ProductGroupID'] try: item.price = Decimal(json['Price']) if item.price < 0: raise ValidationError("Price must be a decimal >= 0") except (ValueError, InvalidOperation): raise ValidationError("Price must be a decimal >= 0") item.has_happy_hour = json['HasHappyHour'] item.service_tax_id = json['ServiceTax']['TaxID'] item.vat_id = json['Vat']['TaxID'] try: item.service_charge = Decimal(json['ServiceCharge']) if item.service_charge <= 0: raise ValidationError("Service Charge must be a decimal > 0") except (ValueError, InvalidOperation): raise ValidationError("Service Charge must be a decimal > 0") item.sc_taxable = json['ScTaxable'] item.is_active = json['IsActive'] try: item.sort_order = Decimal(json['SortOrder']) if item.sort_order < 0: raise ValidationError("Sort Order must be a decimal >= 0") except (ValueError, InvalidOperation): raise ValidationError("Sort Order must be a decimal >= 0") return product_info(item.id) def delete_product(id): with session_scope() as DBSession: item = Product.by_id(id, session=DBSession) # TODO: Proper advanced delete checking # 'Advanced Delete' advance_delete = True can_delete, reason = item.can_delete(advance_delete) if can_delete: delete_with_data(item, DBSession) return product_info(None) else: raise ValidationError("Cannot delete product because {0}".format(reason)) def show_list(): with session_scope() as DBSession: list = DBSession.query(Product).order_by(Product.sort_order).order_by(Product.name).all() products = [] for item in list: products.append({'Name': item.name, 'Units': item.units, 'ProductGroup': {'Name': item.product_group.name}, 'Price': item.price, 'HasHappyHour': item.has_happy_hour, 'ServiceTax': {'Name': item.service_tax.name, 'Rate': item.service_tax.rate}, 'Vat': {'Name': item.vat.name, 'Rate': item.vat.rate}, 'ServiceCharge': item.service_charge, 'ScTaxable': item.sc_taxable, 'IsActive': item.is_active, 'IsFixture': item.is_fixture, 'SortOrder': item.sort_order}) return products def product_info(id): with session_scope() as DBSession: if id is None: item = {'Name': '', 'Units': '', 'ProductGroup': {'ProductGroupID': None}, 'Price': 0, 'HasHappyHour': False, 'ServiceTax': {'TaxID': None}, 'Vat': {'TaxID': None}, 'ServiceCharge': 0, 'ScTaxable': True, 'IsActive': True, 'IsFixture': False, 'SortOrder': 0} else: product = Product.by_id(id, session=DBSession) item = {'ProductID': product.id, 'Name': product.name, 'Units': product.units, 'ProductGroup': {'ProductGroupID': product.product_group.id, 'Name': product.product_group.name}, 'Price': product.price, 'HasHappyHour': product.has_happy_hour, 'ServiceTax': {'TaxID': product.service_tax.id, 'Name': product.service_tax.name, 'Rate': product.service_tax.rate}, 'Vat': {'TaxID': product.vat.id, 'Name': product.vat.name, 'Rate': product.vat.rate}, 'ServiceCharge': product.service_charge, 'ScTaxable': product.sc_taxable, 'IsActive': product.is_active, 'IsFixture': product.is_fixture, 'SortOrder': product.sort_order} return item def delete_with_data(product, *, session=None): pass # suspense_product = Product.by_id(Product.suspense(), session=session) # query = Voucher.query().options(joinedload_all(Voucher.inventories, Inventory.product, innerjoin=True)) \ # .filter(Voucher.inventories.any(Inventory.product_id == product.id)) \ # .all() # # for voucher in query: # others, sus_inv, prod_inv = False, None, None # for inventory in voucher.inventories: # if inventory.product_id == product.id: # prod_inv = inventory # elif inventory.product_id == Product.suspense(): # sus_inv = inventory # else: # others = True # if not others and voucher.type == VoucherType.by_id('Issue'): # DBSession.delete(voucher) # else: # if sus_inv is None: # prod_inv.product = suspense_product # prod_inv.quantity = prod_inv.amount # prod_inv.rate = 1 # prod_inv.tax = 0 # prod_inv.discount = 0 # prod_inv.batch = suspense_batch # voucher.narration += '\nSuspense \u20B9{0:,.2f} is {1}'.format(prod_inv.amount, product.name) # else: # sus_inv.quantity += prod_inv.amount # DBSession.delete(prod_inv) # voucher.narration += '\nDeleted \u20B9{0:,.2f} of {1}'.format(prod_inv.amount, product.name) # for batch in product.batches: # DBSession.delete(batch) # DBSession.delete(product)