Rev 34205 | Blame | Compare with Previous | Last modification | View Log | RSS feed
# -*- coding: utf-8 -*-'''Created on 29-Mar-2010@author: Chandranshu'''from datetime import date, timedeltafrom decimal import Decimalfrom elixir import *from expiringdict import ExpiringDictfrom math import ceilfrom random import randrangefrom reportlab.lib import colorsfrom reportlab.lib.enums import TA_CENTER, TA_JUSTIFYfrom reportlab.lib.styles import ParagraphStyle, getSampleStyleSheetfrom reportlab.lib.units import inch, mmfrom reportlab.pdfgen.canvas import Canvasfrom reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Image, \BaseDocTemplate, Frame, PageTemplate, Table, TableStylefrom reportlab.rl_config import defaultPageSizefrom shop2020.clients.AlertClient import AlertClientfrom shop2020.clients.CRMClient import CRMClientfrom shop2020.clients.CatalogClient import CatalogClientfrom shop2020.clients.HelperClient import HelperClientfrom shop2020.clients.InventoryClient import InventoryClientfrom shop2020.clients.LogisticsClient import LogisticsClientfrom shop2020.clients.PaymentClient import PaymentClientfrom shop2020.clients.PromotionClient import PromotionClientfrom shop2020.clients.UserClient import UserClientfrom shop2020.clients.WarehouseClient import WarehouseClientfrom shop2020.config.client.ConfigClient import ConfigClientfrom shop2020.model.v1 import orderfrom shop2020.model.v1.order.impl import DataService, RechargeServicefrom shop2020.model.v1.order.impl.Convertors import to_t_emi_scheme, to_t_order, \cutoff_date, to_t_warehouse_addressfrom shop2020.model.v1.order.impl.DataService import Transaction, LineItem, \Order, BatchNoGenerator, InvoiceIDGenerator, TransactionRequiringExtraProcessing, \OrderInventory, Alert, PaymentSettlement, EBSSettlementSummary, \CodVerificationAgent, Attribute, RechargeVoucherTracker, EmiScheme, MiscCharges, \BlockedIpRange, DeniedIpAddress, InsuranceDetailForOrder, DocumentStore, \RechargeTransaction, HotspotStore, WalletForCompany, WalletHistoryForCompany, \FRC, OperatorSeries, SourceDetail, Company, EbayOrder, AmazonFbaSalesSnapshot, \AmazonOrder, StoreOrderDetail, EdcBank, StoreOrderCollection, \HotspotServiceMatrix, SnapdealOrder, FlipkartOrder, DataInsuranceDetailForOrder, \AmazonFbaOrderReturns, FlipkartAdvantageOrder, InvoiceCounterGenerator, \TransactionShipmentSequence, HsOrder, Creditor, UserSanction, CreditHistory, \LoanHistory, ShipmentLogisticsCostDetail, ReturnOrderInfo, ReturnTransaction, \ReturnPickupRequest, SellerWarehouse, Seller, Organisation, \WarehouseAddressMapping, WarehouseAddressMaster, PMSA, PMSA_Agents, \AdvancePayments, CodCourierPaymentRemittance, Price_Drop, Price_Drop_IMEI,\PendingRechargeCommissions, Line_Item_Imeifrom shop2020.model.v1.order.impl.model.BaseOrder import BaseOrderfrom shop2020.model.v1.order.impl.model.DTHRechargeOrder import DTHRechargeOrderfrom shop2020.model.v1.order.impl.model.MobileRechargeOrder import \MobileRechargeOrderfrom shop2020.model.v1.order.impl.model.RechargeDenomination import \RechargeDenominationfrom shop2020.model.v1.order.impl.model.RechargeOrder import RechargeOrderfrom shop2020.model.v1.order.impl.model.RechargePlan import RechargePlanfrom shop2020.model.v1.order.impl.model.ReturnOrder import ReturnOrderfrom shop2020.model.v1.order.impl.model.ServiceAvailability import \ServiceAvailabilityfrom shop2020.model.v1.order.impl.model.ServiceProvider import ServiceProviderfrom shop2020.model.v1.order.impl.model.TelecomCircle import TelecomCirclefrom shop2020.model.v1.order.impl.model.UserWallet import UserWalletfrom shop2020.model.v1.order.impl.model.UserWalletHistory import \UserWalletHistoryfrom shop2020.model.v1.user.impl.Converters import to_t_addressfrom shop2020.thriftpy.alert.ttypes import MonitoredEntity, EntityTypefrom shop2020.thriftpy.crm.ttypes import *from shop2020.thriftpy.logistics.ttypes import DeliveryType, PickUpTypefrom shop2020.thriftpy.model.v1.catalog.ttypes import ItemType, ItemConditionfrom shop2020.thriftpy.model.v1.inventory.ttypes import BillingType, \InventoryServiceException, WarehouseType, InventoryType, VatType, ItemInventory, \WarehouseLocationfrom shop2020.thriftpy.model.v1.order.ttypes import TransactionServiceException, \TransactionStatus, OrderStatus, DelayReason, ExtraTransactionProcessingType, \HotspotAction, TimeoutSummary, OrderStatusGroups, OrderType, RechargeOrderStatus, \RechargeType, RechargeStatistics, DeviceNumberInfo, EmiChargeType, PayMethod, \OrderSource, StorePaymentStatus, ProductCondition, TaxType, \AmazonFCWarehouseLocation, RechargeMode, CreditTxnType, \CreditHistory as TCreditHistory, LoanHistory as TLoanHistory, \ShipmentLogisticsCostDetail as TShipmentLogisticsCostDetail, \ReturnTransactionStatus, ReturnAction, ReturnTxnResolutionStatus, \ReplacementShippingType, ReturnTxnPickupStatus, ReceivedReturnType, \ReturnPickupType, RefundType, SellerInfo, BuyerInfo, WalletReferenceTypefrom shop2020.thriftpy.model.v1.user.ttypes import VoucherType, CouponCategory, \User, Sexfrom shop2020.thriftpy.payments.ttypes import PaymentException, PaymentStatusfrom shop2020.thriftpy.utils.ttypes import UserSmsInfo, SmsTypefrom shop2020.thriftpy.warehouse.ttypes import ScanType, \WarehouseServiceExceptionfrom shop2020.utils.EmailAttachmentSender import mail, get_attachment_part, \mail_htmlfrom shop2020.utils.Utils import to_py_date, to_java_date, \getSyncOperatorsForRecharge, generate_random_codefrom sqlalchemy.orm import aliased, joinedloadfrom sqlalchemy.orm.exc import NoResultFound, MultipleResultsFoundfrom sqlalchemy.sql import funcfrom sqlalchemy.sql.expression import and_, or_, desc, not_, distinct, cast, \betweenfrom string import Templatefrom suds.client import Clientfrom textwrap import dedentfrom xml.dom.minidom import parseStringimport MySQLdbimport base64import collectionsimport datetimeimport httplibimport loggingimport mathimport osimport reimport sysimport timeimport tracebackimport urllibfrom shop2020.utils.caching.SimpleCaching import memoized#Start:- Added By Manish Sharma for Creating a new Ticket: Category- RTO Refund on 21-Jun-2013#End:- Added By Manish Sharma for Creating a new Ticket: Category- RTO Refund on 21-Jun-2013#Start:- Added By Manish Sharma for Creating a new Ticket: Category- RTO Refund on 21-Jun-2013#End:- Added By Manish Sharma for Creating a new Ticket: Category- RTO Refund on 21-Jun-2013logging.basicConfig(level=logging.DEBUG)sourceId = int(ConfigClient().get_property("sourceid"))capitalFloatPayMethod = 456789SaholicHelpEmailId = "SmartDukaan <care@smartdukaan.com>"mail_user = 'cnc.center@shop2020.in'mail_password = '5h0p2o2o'help_user = 'help@shop2020.in'help_password = '5h0p2o2o'source_url = 'www.saholic.com'source_name = 'SmartDukaan'hotspot_store_url ='http://125.19.98.100/loaddetect/service.asmx?WSDL'aclient = NonePREPAID_SHIPPING_CUTOFF_TIME = 15COD_SHIPPING_CUTOFF_TIME = 12PAGE_HEIGHT=defaultPageSize[1]PAGE_WIDTH=defaultPageSize[0]billedOrdersColorMap = {}ORDER_STATUS_TO_USER_TRUST_LEVEL_DELTA_DICT = {OrderStatus.RTO_RESHIPPED : 3,OrderStatus.RTO_IN_TRANSIT : -5,OrderStatus.DELIVERY_SUCCESS : 1,OrderStatus.DOA_CERT_INVALID : -5}creditTxnMultiplierMap = {CreditTxnType.BLOCKED : 1,CreditTxnType.BLOCKED_REVERSED : -1,CreditTxnType.LOAN : -1,CreditTxnType.CORRECTION : 1}loanTxnMultplierMap = {CreditTxnType.LOAN : 1,CreditTxnType.LOAN_CANCELLED : -1,CreditTxnType.PAID : -1,CreditTxnType.CORRECTION : -1}refund_status_transition = { OrderStatus.LOST_IN_TRANSIT : OrderStatus.LOST_IN_TRANSIT_REFUNDED,OrderStatus.RTO_RECEIVED_PRESTINE : OrderStatus.RTO_REFUNDED,OrderStatus.RTO_RECEIVED_DAMAGED : OrderStatus.RTO_DAMAGED_REFUNDED,OrderStatus.RTO_LOST_IN_TRANSIT : OrderStatus.RTO_LOST_IN_TRANSIT_REFUNDED,OrderStatus.DOA_CERT_INVALID : OrderStatus.DOA_INVALID_REFUNDED,OrderStatus.DOA_CERT_VALID : OrderStatus.DOA_VALID_REFUNDED,OrderStatus.DOA_RECEIVED_DAMAGED : OrderStatus.DOA_REFUNDED_RCVD_DAMAGED,OrderStatus.DOA_LOST_IN_TRANSIT : OrderStatus.DOA_REFUNDED_LOST_IN_TRANSIT,OrderStatus.RET_PRODUCT_UNUSABLE : OrderStatus.RET_PRODUCT_UNUSABLE_REFUNDED,OrderStatus.RET_PRODUCT_USABLE : OrderStatus.RET_PRODUCT_USABLE_REFUNDED,OrderStatus.RET_RECEIVED_DAMAGED : OrderStatus.RET_REFUNDED_RCVD_DAMAGED,OrderStatus.RET_LOST_IN_TRANSIT : OrderStatus.RET_REFUNDED_LOST_IN_TRANSIT,OrderStatus.COD_VERIFICATION_PENDING : OrderStatus.COD_VERIFICATION_FAILED,OrderStatus.SUBMITTED_FOR_PROCESSING : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,OrderStatus.INVENTORY_LOW : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,OrderStatus.LOW_INV_PO_RAISED : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,OrderStatus.LOW_INV_REVERSAL_IN_PROCESS : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,OrderStatus.ACCEPTED : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,OrderStatus.BILLED : OrderStatus.CANCELLED_ON_CUSTOMER_REQUEST,OrderStatus.CANCEL_REQUEST_CONFIRMED : OrderStatus.CANCELLED_ON_CUSTOMER_REQUEST}creditorTicketSizeMap = {}creditorDueDateMap = {}stateIdMap = {}gvGatewayId = 9walletGatewayId = 8HOURS=3600CACHE_THREE_HOURS = ExpiringDict(max_len=10, max_age_seconds=3*HOURS)dthRechargeCommission = 1.6mobileRechargeCommission = 0.8def fetchStateMaster():if not CACHE_THREE_HOURS.get("statemaster"):try:inventory_client = InventoryClient().get_client()CACHE_THREE_HOURS["statemaster"] = inventory_client.getStateMaster()except:print "Could not fetch"return CACHE_THREE_HOURS.get("statemaster")def fetchCreditorTicketSizeMap():global creditorTicketSizeMapallCreditors = Creditor.query.all()for creditor in allCreditors:creditorTicketSizeMap[creditor.id] = creditor.ticket_sizedef fetchCreditorDueDateMap():global creditorDueDateMapallCreditors = Creditor.query.all()for creditor in allCreditors:creditorDueDateMap[creditor.id] = creditor.credit_due_daysdelhi_pincodes = ['110001','110002','110003','110004','110005','110006','110007','110008','110009','110010','110011','110012','110013','110014','110015',\'110016','110017','110018','110019','110020','110021','110022','110023','110024','110025','110026','110027','110028','110029','110030',\'110031','110032','110033','110034','110035','110037','110038','110041','110042','110044','110045','110046','110047','110048','110049',\'110051','110052','110053','110054','110055','110056','110057','110058','110059','110060','110061','110062','110063','110064','110065',\'110066','110067','110068','110070','110071','110074','110075','110076','110078','110081','110082','110083','110084','110085','110086',\'110087','110088','110089','110091','110092','110093','110094','110095','110096','110101','110103','110104','110105','110106','110107',\'110108','110109','110110','110112','110113','110114','110115','110116','110117','110118','110119','110120','110122','110124','110125',\'110301','110302','110501','110502','110503','110504','110505','110510','110511','110512','110601','110602','110603','110604','110605',\'110606','110607','110608','110609']def getDbConnection(db_host, db_user, db_password, db_name):return MySQLdb.connect(db_host, db_user, db_password, db_name)def closeConnection(conn):conn.close()def get_store_account_client():global aclientif aclient is None:aclient = Client(hotspot_store_url, timeout=70)return aclientdef get_new_transaction():transaction = Transaction()transaction.createdOn = datetime.datetime.now()transaction.status = TransactionStatus.INITtransaction.status_message = "New transaction"return transactiondef create_order(t_order):order = Order()if t_order.warehouse_id:order.warehouse_id = t_order.warehouse_idorder.fulfilmentWarehouseId = t_order.fulfilmentWarehouseIdif t_order.logistics_provider_id:order.logistics_provider_id = t_order.logistics_provider_idorder.airwaybill_no = t_order.airwaybill_noorder.tracking_id = t_order.tracking_idif t_order.expected_shipping_time:order.expected_shipping_time = to_py_date(t_order.expected_shipping_time).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)order.promised_shipping_time = order.expected_shipping_timeif t_order.expected_delivery_time:order.expected_delivery_time = to_py_date(t_order.expected_delivery_time)order.promised_delivery_time = order.expected_delivery_timeif t_order.customer_id:order.customer_id = t_order.customer_idorder.customer_name = t_order.customer_nameorder.customer_city = t_order.customer_cityorder.customer_state = t_order.customer_stateorder.customer_mobilenumber = t_order.customer_mobilenumberorder.customer_pincode = t_order.customer_pincodeorder.customer_address1 = t_order.customer_address1order.customer_address2 = t_order.customer_address2order.customer_email = t_order.customer_email#new status and status description to be addedorder.status = t_order.statusorder.statusDescription = t_order.statusDescriptionorder.total_amount = t_order.total_amountorder.gvAmount = t_order.gvAmountorder.cod = t_order.codorder.total_weight = t_order.total_weightif t_order.created_timestamp:order.created_timestamp = to_py_date(t_order.created_timestamp)else:order.created_timestamp = datetime.datetime.now()order.pickupStoreId = t_order.pickupStoreIdif t_order.insurer:order.insurer = t_order.insurerorder.insuranceAmount = t_order.insuranceAmountif order.insurer > 0:insuranceDetail = InsuranceDetailForOrder()insuranceDetail.dob = t_order.dobinsuranceDetail.guardianName = t_order.guardianNameinsuranceDetail.order = orderif t_order.freebieItemId:order.freebieItemId = t_order.freebieItemIdif OrderSource.MOBILESITE == t_order.source or OrderSource.WEBSITE == t_order.source:order.source = OrderSource.WEBSITEelse:order.source = t_order.source#Change this temporaryif t_order.orderType is None or t_order.orderType ==OrderType.B2C:order.orderType = OrderType.B2Corder.advanceAmount = t_order.advanceAmountorder.storeId = t_order.storeIdif t_order.productCondition:order.productCondition = t_order.productConditionif t_order.dataProtectionInsurer:order.dataProtectionInsurer = t_order.dataProtectionInsurerorder.dataProtectionAmount = t_order.dataProtectionAmountif order.dataProtectionInsurer > 0:dataInsuranceDetail = DataInsuranceDetailForOrder()dataInsuranceDetail.order = orderif t_order.taxType:order.taxType = t_order.taxTypeif t_order.shippingCost:order.shippingCost = t_order.shippingCostif t_order.codCharges:order.codCharges = t_order.codChargesorder.wallet_amount = t_order.wallet_amountorder.net_payable_amount = t_order.net_payable_amountreturn orderdef create_transaction(t_transaction):t_orders = t_transaction.ordersif not t_orders:raise TransactionServiceException(101, "Orders missing from the transaction")transaction = get_new_transaction()transaction.customer_id = t_transaction.customer_idtransaction.shopping_cart_id = t_transaction.shoppingCartidtransaction.coupon_code = t_transaction.coupon_codetransaction.session_source = t_transaction.sessionSourcetransaction.session_start_time = to_py_date(t_transaction.sessionStartTime)transaction.first_source = t_transaction.firstSourcetransaction.first_source_start_time = to_py_date(t_transaction.firstSourceTime)transaction.payment_option = t_transaction.payment_optionif t_transaction.totalShippingCost:transaction.totalShippingCost = t_transaction.totalShippingCostif t_transaction.totalCodCharges:transaction.totalCodCharges = t_transaction.totalCodChargesuser_client = UserClient().get_client()user_client.getCounterByUserId(t_transaction.customer_id)totalAmount = 0wallet_amount = 0.0for t_order in t_orders:order = create_order(t_order)totalAmount = totalAmount + order.total_amountwallet_amount = wallet_amount + order.wallet_amountorder.transaction = transactionfor line_item in t_order.lineitems:litem = LineItem()litem.item_id = line_item.item_idlitem.productGroup = line_item.productGrouplitem.brand = line_item.brandlitem.hsnCode = line_item.hsnCodeif line_item.model_number:litem.model_number = line_item.model_numberif line_item.model_name:litem.model_name = line_item.model_nameif line_item.color:litem.color = line_item.colorif line_item.extra_info:litem.extra_info = line_item.extra_infolitem.quantity = line_item.quantitylitem.unit_price = line_item.unit_priceif line_item.mrp:litem.mrp = line_item.mrplitem.unit_weight = line_item.unit_weightlitem.total_price = line_item.total_pricelitem.total_weight = line_item.total_weighttry:litem.transfer_price = line_item.transfer_pricelitem.nlc = line_item.nlcexcept Exception as e:print "Exception while setting transfer price and nlc" + str(e.message)print sys.exc_info()[0]'''litem.transfer_price = line_item.transfer_price'''litem.dealText = line_item.dealTextlitem.warranty_expiry_timestamp = to_py_date(line_item.warrantry_expiry_timestamp)"""if line_item.addedOn:litem.added_on = to_py_date(line_item.addedOn)else:litem.added_on = datetime.datetime.now()"""litem.order = ordersession.commit()for order1 in Transaction.get_by(id=transaction.id).orders:if OrderSource.MOBILESITE == order.source or OrderSource.WEBSITE == order.source:attribute = Attribute()attribute.orderId = order1.idattribute.name = "OrderSource"if OrderSource.MOBILESITE == order1.source:attribute.value = "Mobile"order1.source = OrderSource.WEBSITEelse:attribute.value = "Desktop"session.commit()# EMI charges can not be charged by merchant as per RBI guidelines.#Now we do not have any other charges, So commenting it out.#generateOtherCharges(transaction, t_transaction.emiSchemeId, totalAmount)"""Update amount in wallet"""return transaction.iddef generateOtherCharges(transaction, emiSchemeId, totalAmount):emiScheme = EmiScheme.get_by(id=emiSchemeId)if not emiScheme:returnif totalAmount < emiScheme.minAmount:returnemiCharge = 0if emiScheme.chargeType == EmiChargeType.FIXED:emiCharge = ceil(emiScheme.chargeValue)if emiScheme.chargeType == EmiChargeType.PERCENTAGE:emiCharge = ceil(totalAmount*(emiScheme.chargeValue)/100)if transaction.coupon_code is not None and transaction.coupon_code != "":try:promotion_client = PromotionClient().get_client()emis = promotion_client.getEmiDiscount(transaction.shopping_cart_id)if emis.has_key(emiSchemeId):discount = emis.get(emiSchemeId)if emiCharge > discount:emiCharge -= discountelse:emiCharge = 0except:print "Could not get emi discounts from promotion"miscCharge = MiscCharges()miscCharge.transaction = transactionmiscCharge.chargeType = 1 ##EMI chargesmiscCharge.chargeAmount = emiChargesession.commit()def get_transaction(transaction_id):transaction = Transaction.get_by(id=transaction_id)if not transaction:raise TransactionServiceException(108, "no such transaction")return transactiondef get_transactions_for_customer(customer_id, from_date, to_date, status):if not customer_id:raise TransactionServiceException(101, "bad customer id")query = Transaction.query.filter(Transaction.customer_id == customer_id)if status is not None:query = query.filter(Transaction.status == status)if from_date:query = query.filter(Transaction.createdOn >from_date)if to_date:query = query.filter(Transaction.createdOn < to_date)return query.all()def get_transactions_for_shopping_cart_id(shopping_cart_id):transactions = Transaction.query.filter_by(shopping_cart_id=shopping_cart_id).all()return transactionsdef get_transaction_status(transaction_id):if not transaction_id:raise TransactionServiceException(101, "bad transaction id")transaction = get_transaction(transaction_id)return transaction.statusdef change_transaction_status(transaction_id, new_status, description, pickUp, orderType, source):logging.info("########change transaction status called" + str(transaction_id))transaction = get_transaction(transaction_id)if new_status in (TransactionStatus.AUTHORIZED, TransactionStatus.FLAGGED, TransactionStatus.COD_IN_PROCESS):wallet_amount_used = 0.0for order in transaction.orders:wallet_amount_used = wallet_amount_used + order.wallet_amountif wallet_amount_used > 0:user_wallet = get_user_wallet(transaction.orders[0].customer_id)if user_wallet and user_wallet.amount < wallet_amount_used:if new_status == TransactionStatus.AUTHORIZED:try:captured_amount = __capture_txn(transaction_id)except:#TODO:##add_amount_in_wallet(transaction.customer_id, captured_amount, transaction_id, WalletReferenceType.PURCHASE, False, "Amount added against failed Purchase", commit_session=True)passreturn Falsepayment_client = PaymentClient().get_client()payments = payment_client.getPaymentForTxnId(order.transaction_id)wallet_payment_exist = Falsefor payment in payments:if payment.gatewayId == walletGatewayId:wallet_payment_exist = Truelogging.info("########Updating wallet")payment_client.updatePaymentDetails(payment.paymentId, "", "", "SUCCESS", "Payment Received", "", "", "", "", PaymentStatus.SUCCESS, "", None);if not wallet_payment_exist:return Falseconsume_wallet(transaction.orders[0].customer_id, wallet_amount_used, transaction_id, WalletReferenceType.PURCHASE, "Against Order purchase")transaction.status = new_statustransaction.status_message = descriptionexpectedDelayMap = {}billingWarehouseIdMap = {}billingWarehouseTxnMap = {}if new_status == TransactionStatus.FAILED:for order in transaction.orders:order.status = OrderStatus.PAYMENT_FAILEDorder.statusDescription = "Payment Failed"elif new_status == TransactionStatus.AUTHORIZED or new_status == TransactionStatus.FLAGGED:user_client = UserClient().get_client()catalog_client = CatalogClient().get_client()pdu = user_client.getPrivateDealUser(transaction.orders[0].customer_id)print "pdu.isFofo----", pdu.isFofofofoWarehousesMap = {}if pdu.isFofo:fofoDealMap = catalog_client.getAllFofoDeals([order.lineitems[0].item_id], [4,7])if fofoDealMap:itemIds = []for order in transaction.orders:itemIds.append(order.lineitems[0].item_id)inventory_client = InventoryClient().get_client()print "calling getFofoFulFillmentWarehouseMap"fofoWarehousesMap = inventory_client.getFofoFulFillmentWarehouseMap(itemIds)print "called getFofoFulFillmentWarehouseMap"expectedDelayMap = {}billingWarehouseIdMap = {}billingWarehouseTxnMap = {}subOrderAmountsMap = {}for order in transaction.orders:if new_status == TransactionStatus.AUTHORIZED:order.status = OrderStatus.SUBMITTED_FOR_PROCESSINGorder.statusDescription = "Submitted to warehouse"elif new_status == TransactionStatus.FLAGGED:order.status = OrderStatus.PAYMENT_FLAGGEDorder.statusDescription = "Payment flagged by gateway"order.cod = False#Order type cant be changed during authorization#if orderType is not None:# order.orderType = orderType#After we got payment success, we will set logistics info alsologistics_client = LogisticsClient().get_client()#FIXME line item is only one now. If multiple will come, need to fix.item_id = order.lineitems[0].item_idif pickUp == PickUpType.RUNNER or pickUp == PickUpType.SELF:current_time = datetime.datetime.now()if pdu.isFofo:stateMaster = fetchStateMaster()stateId = -1for k, v in stateMaster.iteritems():if v.stateName == order.customer_state:stateId = kbreaklogistics_info = logistics_client.getLogisticsInfo(order.customer_pincode, item_id, DeliveryType.PREPAID, pickUp, stateId)else:logistics_info = logistics_client.getLogisticsInfo(order.customer_pincode, item_id, DeliveryType.PREPAID, pickUp, -1)order.logistics_provider_id = logistics_info.providerIdorder.warehouse_id = logistics_info.warehouseIdorder.fulfilmentWarehouseId = logistics_info.fulfilmentWarehouseIdlogistics_info.deliveryTime = adjust_delivery_time(current_time, logistics_info.deliveryTime)logistics_info.shippingTime = adjust_delivery_time(current_time, logistics_info.shippingTime)logistics_info.deliveryDelay = adjust_delivery_time(current_time, (logistics_info.shippingTime+logistics_info.deliveryDelay))order.courier_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryDelay)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)order.expected_shipping_time = (current_time + datetime.timedelta(days=logistics_info.shippingTime)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)order.promised_shipping_time = order.expected_shipping_timeorder.expected_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryTime)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)order.promised_delivery_time = order.expected_delivery_timeorder.otg = Falseinventory_client = InventoryClient().get_client()if order.productCondition != ProductCondition.BAD:inventory_client.reserveItemInWarehouse(item_id, order.fulfilmentWarehouseId, sourceId, order.id, to_java_date(order.created_timestamp), to_java_date(order.promised_shipping_time), order.lineitems[0].quantity)elif order.source == OrderSource.WEBSITE:try:#Get the id and location of actual warehouse that'll be used to fulfil this order.inventory_client = InventoryClient().get_client()fulfilmentWhId, expected_delay, billingWarehouseId, sellingPrice, totalAvailability, weight = inventory_client.getItemAvailabilityAtLocation(item_id, 1, -1)except Exception as ex:raise TransactionServiceException(103, "Unable to fetch inventory information about this item.")expectedDelayMap[item_id] = expected_delayif billingWarehouseIdMap.has_key(billingWarehouseId):ordersList = billingWarehouseIdMap.get(billingWarehouseId)ordersList.append(order)billingWarehouseIdMap[billingWarehouseId] = ordersListelse:ordersList = []ordersList.append(order)billingWarehouseIdMap[billingWarehouseId] = ordersListif billingWarehouseTxnMap.has_key(billingWarehouseId):transactionAmount , transactionWeight = billingWarehouseTxnMap.get(billingWarehouseId)transactionAmount = transactionAmount+order.total_amounttransactionWeight = transactionWeight+order.total_weightbillingWarehouseTxnMap[billingWarehouseId] = transactionAmount , transactionWeightelse:billingWarehouseTxnMap[billingWarehouseId] = order.total_amount , order.total_weightsubOrderAmountsMap[long(order.lineitems[0].unit_price)] = orderorder.fulfilmentWarehouseId = fulfilmentWhIdorder.warehouse_id = billingWarehouseIdif order.productCondition != ProductCondition.BAD:inventory_client.reserveItemInWarehouse(item_id, order.fulfilmentWarehouseId, sourceId, order.id, to_java_date(order.created_timestamp), to_java_date(order.promised_shipping_time), order.lineitems[0].quantity)try:item_pricing = inventory_client.getItemPricing(item_id, -1)order.lineitems[0].transfer_price = item_pricing.transferPriceorder.lineitems[0].nlc = item_pricing.nlcexcept:print "Not able to get transfer price. Skipping"session.commit()return Truedef __create_recharge_voucher_tracker(order, amount, voucherType):rvt = RechargeVoucherTracker()rvt.order = orderrvt.amount = amountrvt.voucherIssued = Falservt.voucherType = voucherTypedef __get_holidays(start_time=0L, to_time=-1L):'''Get the list of all public holidays since start time including theday of start time if it's a holiday'''midnightTime = start_time.replace(hour=0, minute=0, second=0, microsecond=0)fromDate = to_java_date(midnightTime)logistics_client = LogisticsClient().get_client()#TODO: This list should be cached after the first call.#Calling logistics server is also unnecessary.holidays = logistics_client.getHolidays(fromDate, to_time)holidays = [to_py_date(holiday).date() for holiday in holidays]return holidaysdef adjust_delivery_time(start_time, delivery_days):'''Returns the actual no. of days which will pass while 'delivery_days'no. of business days will pass since 'order_time'.'''start_date = start_time.date()end_date = start_date + datetime.timedelta(days = delivery_days)holidays = __get_holidays(start_time)while start_date <= end_date:if start_date.weekday() == 6 or start_date in holidays:delivery_days = delivery_days + 1end_date = end_date + datetime.timedelta(days = 1)start_date = start_date + datetime.timedelta(days = 1)return delivery_daysdef adjust_shipping_time(delivery_date, delay):shipping_date=delivery_date - datetime.timedelta(days = delay)holidays = __get_holidays(shipping_date)while(True):if shipping_date.weekday() == 6 or shipping_date in holidays:shipping_date = shipping_date - datetime.timedelta(days = 1)else:return shipping_datedef get_business_days_count(start_time, end_time):'''Returns business dates between two dates'''start_date = start_time.date()end_date = end_time.date()diff = (end_date - start_date).dayssundays = diff/7 + 1 if (start_date.weekday() + (diff%7) > 6) else diff/7'''holidays = __get_holidays(start_time, end_time)'''logistics_client = LogisticsClient().get_client()#TODO: This list should be cached after the first call.#Calling logistics server is also unnecessary.holidays = logistics_client.getHolidays(to_java_date(start_time), to_java_date(end_time))non_business_days = len(holidays)for holiday in holidays:pyholiday = to_py_date(holiday).date()if pyholiday.weekday() == 6:sundays = sundays - 1return diff - (non_business_days + sundays)def enqueue_transaction_info_email(transaction_id):transaction = get_transaction(transaction_id)#Dear Customer, thanks for placing order of Spice Stellar Mi-535 Black and 5 other items amounting Rs. 25000. Check your email for details.smsText = "Dear Customer, Thanks for placing order of "mobileNo = NonecustomerId = 0sendSms = TruetransactionAmount = 0.0orderQuantity = 0totalQuantity = 0itemQuantityMap = {}itemNameMap = {}oneProduct = ""subject = source_name + " - Order Details"orders = transaction.ordersadvance_amount = orders[0].advanceAmountsaddress = ""for order in orders:if order.pickupStoreId:sendSms= FalsetransactionAmount = transactionAmount + order.total_amount + order.shippingCostfor lineitem in order.lineitems:if itemQuantityMap.has_key(lineitem.item_id):quantity = itemQuantityMap.get(lineitem.item_id)quantity = quantity + lineitem.quantityitemQuantityMap[lineitem.item_id] = quantityelse:itemQuantityMap[lineitem.item_id] = lineitem.quantityif not itemNameMap.has_key(lineitem.item_id):itemNameMap[lineitem.item_id] = str(lineitem)if len(itemNameMap) == 1:for itemId, itemName in itemNameMap.iteritems():oneProduct = itemNameorderQuantity = itemQuantityMap.get(itemId)if len(oneProduct) > 30:oneProduct = oneProduct[0:28]+"..."smsText = smsText + oneProduct +". Total "+ str(long(orderQuantity)) +"pc(s), amount Rs " + str(long(transactionAmount))if len(itemNameMap) >1:for itemId, itemName in itemNameMap.iteritems():oneProduct = itemNametotalQuantity = totalQuantity + itemQuantityMap.get(lineitem.item_id)itemQuantityMap.pop(lineitem.item_id)breakfor itemId, quantity in itemQuantityMap.iteritems():orderQuantity = orderQuantity + quantitytotalQuantity = totalQuantity + quantityif len(oneProduct) > 30:oneProduct = oneProduct[0:28]+"..."smsText = smsText + oneProduct +" and "+str(long(orderQuantity))+ " other item(s). Total " + str(long(totalQuantity)) +"pcs, amount Rs "+ str(long(transactionAmount))smsText = smsText + ". Check your email for details."bcc = []if advance_amount > 0:store = get_hotspot_store(orders[0].storeId, "")bcc = bcc + store.approvalEmail.split(';') + [store.email, "amit.gupta@shop2020.in", "rajneesh.arora@shop2020.in", "amit.sirohi@shop2020.in"]saddress += " at our store " + __get_hotspot_store_address_html(store)otgLink = ""inOrderOtg = "<div>On Time Guarantee<br><span style=color:red>We pay if we delay</span></div>"if len(transaction.orders) == 1:inOrderOtg = ""if transaction.orders[0].otg :subject = "Your Order is confirmed with On Time Guarantee We Pay if we Delay"otgLink = ' Your Order is covered under the <a href="http://www.saholic.com/static/on-time-guarantee">On Time Guarantee, We pay If we Delay.</a>'customer_name = ""html_header = """<html><body><div><p>Hello $customer_name,<br /><br />Thanks for placing order with us $saddress .$otgLink Following are the details of your order:</p><div>Order Date: $order_date</div><div><table><tr><td colspan="6"><hr /></td></tr><tr><td colspan="6" align="left"><b>Order Details</b></td></tr><tr><td colspan="6"><hr /></td></tr><tr><th width="100">Order No.</th><th>Product</th><th width="100">Estimated Delivery Date</th><th width="100">Quantity</th><th width="100">Unit Price</th><th width="100">Amount</th></tr>"""user_email = ""total_amount = 0.0total_shipping = 0.0html_table = ""order_date = datetime.datetime.now()html_pickup_text = ""random_text = ""if orders[0].pickupStoreId:random_text = str(randrange(100000, 999999))first = Truefor order in orders:mobileNo = order.customer_mobilenumbercustomerId = order.customer_idcustomer_name = order.customer_nameorder_date = order.created_timestampuser_email = order.customer_emailif first:first = Falsehtml_tr = ""else:html_tr = "<tr><td colspan=6> </td></tr>"html_tr += "<tr><td align='center'>" + str(order.id) + "</td>"sdt = datetime.datetime.strptime(str(orders[0].expected_delivery_time), "%Y-%m-%d %H:%M:%S")store_delivery_date = sdt.strftime("%d %B %Y")total_amount += order.shippingCosttotal_shipping += order.shippingCostif order.pickupStoreId:attribute = Attribute()attribute.orderId = order.idattribute.name = "SECRET_CODE"attribute.value = random_textsession.commit()for lineitem in order.lineitems:lineitem_total_price = round(lineitem.total_price, 2)html_tr += "<td>" + str(lineitem) + "</td>"if order.otg:html_tr += "<td align='center'><div>" + store_delivery_date + "</div>" + inOrderOtg + "</td>"else:html_tr += "<td align='center'>" + store_delivery_date + "</td>"html_tr += "<td align='center'>" + ("%.0f" % lineitem.quantity) + "</td>"html_tr += "<td align='center'> Rs. " + ("%.2f" % lineitem.unit_price) + "</td>"html_tr += "<td align='center'> Rs. " + ("%.2f" % lineitem_total_price) + "</td></tr>"total_amount += lineitem_total_pricehtml_table += html_trif order.freebieItemId:catalog_client = CatalogClient().get_client()item = catalog_client.getItem(order.freebieItemId)html_table += "<tr><td align='center'></td><td style='font-style:italic;' colspan='5'> Free Item: "+item.brand + " " + item.modelName + " " + item.modelNumber+"</td></tr>"if order.insurer:html_table += "<tr><td colspan=6> </td></tr>"html_table += "<tr><td align='center'></td><td style='font-style:italic;'>Insured Against Theft for 1 Year. <a href='http://www.saholic.com/static/insurance-terms'>Know More</a></td><td align='center'></td><td align='center'></td><td align='center'></td>"html_table += "<td align='center'>" + str(order.insuranceAmount) + "</td></tr>"total_amount += order.insuranceAmountemi_amount = 0miscCharges = get_misc_charges(transaction_id)if miscCharges.get(1):emi_amount = miscCharges.get(1)html_footer = """<tr><td colspan=6> </td></tr><tr><td colspan=6><hr /></td></tr>"""if emi_amount > 0:total_amount += emi_amounthtml_footer = html_footer + "<tr>\<td colspan=5>EMI Processing Charges</td>\<td> Rs. $emi_amount</td>\</tr>"amount_string = "Total Amount"if advance_amount > 0:amount_string = "Balance Amount"total_amount -= advance_amounthtml_footer = html_footer + "<tr>\<td colspan=5>Advance Paid</td>\<td> Rs. $advance_amount</td>\</tr>"shipping_string = "Shipping Charges"if total_shipping > 0:html_footer = html_footer + "<tr>\<td colspan=5>$shipping_string</td>\<td> Rs. $total_shipping</td>\</tr>"html_footer = html_footer + "<tr>\<td colspan=5>$amount_string</td>\<td> Rs. $total_amount</td>\</tr>\</table>\</div>"#Commenting out fog message#html_footer = html_footer + "Note:- With the onset of dense fog in North India, it severely hits the operations of our courier partners. We would like to mention that our deliveries might be slightly delayed. We look forward to your support and understanding with regards to anticipated delays.<br>"store_address = ""if orders[0].pickupStoreId:store = LogisticsClient().get_client().getPickupStore(orders[0].pickupStoreId)store_address = __get_store_address_html(store)html_pickup_text = html_pickup_text + """<h3>Steps to Pickup In Store</h3>1) You will receive a confirmation email from us when your product(s) reaches the store. Once you receive the same, please visit the following store selected by you.<br><br><i>$store_address</i><br>"""if orders[0].cod:html_pickup_text = html_pickup_text + """2) Pay Rs. $net_amount, present a photo copy of valid Photo Identity Proof* and use your Secret Code <b><i>$secret_code</i></b> to claim your Product(s).<br><br>*Valid Photo Identity Proof are Driving License, Passport, PAN Card, Voter ID, Company Issued ID Card, College issued Student ID Card Or any other Government approved Photo Id.<br><br>In case you have any questions please visit <a href="$source_url/static/buy-online-and-pickup-in-store">Details on Pickup in Store</a>. If you still have more questions feel free to contact us 24/7 via <a href="$source_url/contact-us">$source_url/contact-us</a></br><hr />"""else:html_pickup_text = html_pickup_text + """2) Present a photo copy of valid Photo Identity Proof* and use your Secret Code <b><i>$secret_code</i></b> to claim your Product(s).<br><br>*Valid Photo Identity Proof are Driving License, Passport, PAN Card, Voter ID, Company Issued ID Card, College issued Student ID Card Or any other Government approved Photo Id.<br><br>In case you have any questions please visit <a href="$source_url/static/buy-online-and-pickup-in-store">Details on Pickup in Store</a>. If you still have more questions feel free to contact us 24/7 via <a href="$source_url/contact-us">$source_url/contact-us</a></br><hr />"""html_store_cust_address = ""if advance_amount > 0:html_store_cust_address += "Your order shall be delivered at " + __get_order_address_html(orders[0])html_footer = html_footer + html_pickup_text + html_store_cust_address + """<p>Best Wishes,<br />$source_name Team</p></div></body></html>"""dt = datetime.datetime.strptime(str(order_date), "%Y-%m-%d %H:%M:%S")formated_order_date = dt.strftime("%A, %d. %B %Y %I:%M%p")sdt = datetime.datetime.strptime(str(orders[0].expected_delivery_time), "%Y-%m-%d %H:%M:%S")store_delivery_date = sdt.strftime("%A, %d %B %Y")email_header = Template(html_header).substitute(dict(order_date = formated_order_date, customer_name = customer_name, source_url = source_url, otgLink = otgLink, saddress = saddress))email_footer = Template(html_footer).substitute(dict(total_amount = "%.2f" % total_amount, emi_amount = "%.2f" % emi_amount, advance_amount = "%.2f" % advance_amount, net_amount = "%.2f" % (total_amount-order.gvAmount), secret_code = random_text, store_address = store_address, store_delivery_date = store_delivery_date, source_url = source_url, source_name = source_name, amount_string = amount_string, shipping_string = shipping_string, total_shipping = "%.2f" % total_shipping))try:helper_client = HelperClient().get_client()helper_client.saveUserEmailForSending([user_email], SaholicHelpEmailId, subject, email_header + html_table + email_footer, str(transaction_id), "TransactionInfo", [], bcc, orders[0].source)if sendSms:send_transaction_sms(customerId, mobileNo, smsText, SmsType.TRANSACTIONAL, False)return Trueexcept Exception as e:print ereturn Falsedef send_transaction_sms(customerId, mobileNo, smsText, smsType, useKey):if useKey:if mobileNo is not None:helper_client = HelperClient(host_key = "helper_service_server_host_prod").get_client()helper_client.saveUserSmsForSending(customerId, mobileNo, smsText, SmsType.TRANSACTIONAL)userSmsInfo = helper_client.getUserSmsInfo(customerId);if customerId == userSmsInfo.userId and mobileNo == userSmsInfo.mobileNo:userSmsInfo.dailyCount = userSmsInfo.dailyCount +1userSmsInfo.weeklyCount = userSmsInfo.weeklyCount +1helper_client.updateUserSmsInfo(userSmsInfo)elif customerId == userSmsInfo.userId and mobileNo != userSmsInfo.mobileNo:userSmsInfo.updateTimestamp = to_java_date(datetime.datetime.now())userSmsInfo.mobileNo = mobileNouserSmsInfo.dailyCount = 1userSmsInfo.weeklyCount = 1helper_client.updateUserSmsInfo(userSmsInfo)else:userSmsInfo = UserSmsInfo()userSmsInfo.userId = customerIduserSmsInfo.mobileNo = mobileNouserSmsInfo.createdTimestamp = to_java_date(datetime.datetime.now())userSmsInfo.updateTimestamp = to_java_date(datetime.datetime.now())helper_client.addUserSmsInfo(userSmsInfo);else:if mobileNo is not None:helper_client = HelperClient().get_client()helper_client.saveUserSmsForSending(customerId, mobileNo, smsText, SmsType.TRANSACTIONAL)userSmsInfo = helper_client.getUserSmsInfo(customerId);if customerId == userSmsInfo.userId and mobileNo == userSmsInfo.mobileNo:userSmsInfo.dailyCount = userSmsInfo.dailyCount +1userSmsInfo.weeklyCount = userSmsInfo.weeklyCount +1helper_client.updateUserSmsInfo(userSmsInfo)elif customerId == userSmsInfo.userId and mobileNo != userSmsInfo.mobileNo:userSmsInfo.updateTimestamp = to_java_date(datetime.datetime.now())userSmsInfo.mobileNo = mobileNouserSmsInfo.dailyCount = 1userSmsInfo.weeklyCount = 1helper_client.updateUserSmsInfo(userSmsInfo)else:userSmsInfo = UserSmsInfo()userSmsInfo.userId = customerIduserSmsInfo.mobileNo = mobileNouserSmsInfo.createdTimestamp = to_java_date(datetime.datetime.now())userSmsInfo.updateTimestamp = to_java_date(datetime.datetime.now())helper_client.addUserSmsInfo(userSmsInfo);def enqueue_received_at_store_email(order):html_header = """<html><body><div><p>Hello $customer_name,<br /><br />Your Product has reached the Store selected by you and is available for pickup. Please pick up your product on or before $order_expiry_date. Following are the details of your order and steps to pickup the same:</p><div>Order Date: $order_date</div><div><table><tr><td colspan="5"><hr /></td></tr><tr><td colspan="5" align="left"><b>Order Details</b></td></tr><tr><td colspan="5"><hr /></td></tr><tr><th width="100">Order No.</th><th>Product</th><th width="100">Quantity</th><th width="100">Unit Price</th><th width="100">Amount</th></tr>"""total_amount = 0.0html_table = ""html_pickup_text = ""random_text = __get_secret_code(order.id)customer_name = order.customer_nameorder_date = order.created_timestampuser_email = order.customer_emailhtml_tr = "<tr><td align='center'>" + str(order.id) + "</td>"for lineitem in order.lineitems:lineitem_total_price = round(lineitem.total_price, 2)html_tr += "<td>" + str(lineitem) + "</td>"html_tr += "<td align='center'>" + ("%.0f" % lineitem.quantity) + "</td>"html_tr += "<td align='center'> Rs. " + ("%.2f" % lineitem.unit_price) + "</td>"html_tr += "<td align='center'> Rs. " + ("%.2f" % lineitem_total_price) + "</td></tr>"total_amount += lineitem_total_pricehtml_table += html_trhtml_footer = """<tr><td colspan=5> </td></tr><tr><td colspan=5><hr /></td></tr><tr><td colspan=4>Total Amount</td><td> Rs. $total_amount</td></tr></table></div>"""store_address = ""if order.pickupStoreId:store = LogisticsClient().get_client().getPickupStore(order.pickupStoreId)store_address = __get_store_address_html(store)html_pickup_text = html_pickup_text + """<h3>Steps to Pickup In Store</h3>1) Please visit the following store selected by you on or before $order_expiry_date<br><br><i>$store_address</i><br>"""if order.cod:html_pickup_text = html_pickup_text + """2) Pay Rs. $net_amount, present a valid Photo Identity Proof* and quote your Secret Code <b><i>$secret_code</i></b> to claim your Product.<br><br>*Valid Photo Identity Proof are Driving License, Passport, PAN Card, Voter ID, Company Issued ID Card, College issued Student ID Card Or any other Government approved Photo Id.<br><br>In case you have any questions please visit <a href="$source_url/static/buy-online-and-pickup-in-store">Details on Pickup in Store</a>. If you still have more questions feel free to contact us 24/7 via <a href="$source_url/contact-us">$source_url/contact-us</a></br><hr />"""else:html_pickup_text = html_pickup_text + """2) Present a valid Photo Identity Proof* and use your Secret Code <b><i>$secret_code</i></b> to claim your Product(s).<br><br>*Valid Photo Identity Proof are Driving License, Passport, PAN Card, Voter ID, Company Issued ID Card, College issued Student ID Card Or any other Government approved Photo Id.<br><br>In case you have any questions please visit <a href="$source_url/static/buy-online-and-pickup-in-store">Details on Pickup in Store</a>. If you still have more questions feel free to contact us 24/7 via <a href="$source_url/contact-us">$source_url/contact-us</a></br><hr />"""html_footer = html_footer + html_pickup_text + """<p>Best Wishes,<br />$source_name Team</p></div></body></html>"""subject = "Your order for " + str(order.lineitems[0]) + " is ready for Pickup in Store"dt = datetime.datetime.strptime(str(order_date), "%Y-%m-%d %H:%M:%S")formated_order_date = dt.strftime("%A, %d. %B %Y %I:%M%p")oetd = datetime.datetime.now() + datetime.timedelta(days=4)formated_order_expiry_date = oetd.strftime("%A, %d %B %Y")email_header = Template(html_header).substitute(dict(order_date = formated_order_date, customer_name = customer_name, order_expiry_date = formated_order_expiry_date, source_url = source_url, source_name = source_name))email_footer = Template(html_footer).substitute(dict(total_amount = "%.2f" % total_amount, net_amount = "%.2f" % (total_amount-order.netAmount), secret_code = random_text, store_address = store_address, order_expiry_date = formated_order_expiry_date, source_url = source_url, source_name = source_name))try:helper_client = HelperClient(host_key = "helper_service_server_host_prod").get_client()helper_client.saveUserEmailForSending([user_email], SaholicHelpEmailId, subject, email_header + html_table + email_footer, str(order.id), "ReceivedAtStore", [], [], order.source)return Trueexcept Exception as e:print ereturn Falsedef enqueue_delivery_success_mail(logisticsTxnId, orderList):order = orderList[0]user_client = UserClient().get_client()if user_client.getPrivateDealUser(order.customer_id).isFofo:return Truehtml_header = """<html><body><div><p>Dear $customer_name,<br /><br /></p>"""html= """<div>Order Date: $order_date <br>$pickup_text</div><div><table><tr><td colspan="8"><hr /></td></tr><tr><td colspan="8" align="left"><b>Order Details</b></td></tr><tr><td colspan="8"><hr /></td></tr><tr><th width="100">Sub Order Id</th><th>Product Name</th><th width="100">Quantity</th><th width="100">Unit Price</th><th width="100">Amount</th><th width="100">Insurance Amount</th><th width="100">OTG Covered</th><th width="100">Freebie Item</th></tr>"""total_amount = 0.0total_shipping = 0.0advanceAmount = 0.0hasOtg = FalseotgCount = 0hasFreebie = FalsehasSplitOrder = FalsehasInsurer = FalsehasPickupStoreOrder = FalsesplitOrdersMap = {}totalUnitPrice = 0.0for orderObj in orderList:lineitem = orderObj.lineitems[0]lineitem_total_price = round(lineitem.total_price, 2)total_amount += lineitem_total_price + orderObj.shippingCostadvanceAmount += orderObj.advanceAmounttotal_shipping += orderObj.shippingCosthtml += """<tr><td align="center">"""+str(orderObj.id)+"""</td><td>"""+str(lineitem)+"""</td><td align="center">"""+("%.0f" % lineitem.quantity)+"""</td><td align="center">"""+("%.2f" % lineitem.unit_price)+"""</td><td align="center">"""+("%.2f" % lineitem_total_price)+"""</td>"""if orderObj.insurer > 0:hasInsurer = Truetotal_amount += orderObj.insuranceAmounthtml += """<td align="center">"""+("%.2f" % orderObj.insuranceAmount) +"""</td>"""else:html += """<td align="center">0.00</td>"""if orderObj.otg:hasOtg = TrueotgCount += 1totalUnitPrice += lineitem.unit_pricehtml += """<td align="center">Yes</td>"""else:html += """<td align="center">No</td>"""if orderObj.freebieItemId:hasFreebie = Truecatalog_client = CatalogClient().get_client()item = catalog_client.getItem(orderObj.freebieItemId)html += """<td align="center">"""+item.brand+" "+item.modelName+ " " + item.modelNumber +"""</td>"""else:html += """<td align="center"></td>"""freebieOrderId = get_order_attribute_value(orderObj.id, "freebieOrderId")if freebieOrderId != "":freebieOrder = get_order(freebieOrderId)hasSplitOrder = TruesplitOrdersMap[orderObj.id] = freebieOrderif orderObj.pickupStoreId:hasPickupStoreOrder = Truehtml += """</tr>"""html += """<tr><td colspan=8> </td></tr><tr><td colspan=8><hr /></td></tr>"""amount_string = "Total Amount"if advanceAmount > 0:html += """<tr><td colspan="7">Advance Amount</td><td>Rs."""+("%.2f" % advanceAmount)+"""</tr>"""total_amount -= advanceAmountamount_string = "Balance Amount"shipping_string = "Shipping Charges"if total_shipping > 0:html = html + """<tr>\<td colspan=7>"""+shipping_string+"""</td>\<td> Rs. """+("%.2f" % total_shipping)+"""</td>\</tr>"""html += """<tr><td colspan="7">"""+amount_string+"""</td><td>Rs."""+("%.2f" % total_amount)+"""</tr>"""html += """</table></div>$freebie_text$insurance_text</div><p>Best Wishes,<br />$source_name Team</p></div></body></html>"""pickup_text =" "if hasPickupStoreOrder:pickup_text = "Pickup Date: " + order.delivery_timestamp.strftime("%A, %d. %B %Y %I:%M%p")thank_you_html = """Thank you for shopping with us and picking up your order in Store.Following are the details of your order $master_order_id for which the pickup has happened. <br> If you have not picked up this product please <a href="$source_url/contact-us" target="_blank">contact us</a> immediately.<br>"""#If you are happy with our services please join us on <a href="https://twitter.com/saholic">Twitter</a>, <a href="http://www.facebook.com/mysaholic">Facebook Page</a> and help us spread the word.<br/>else:if hasOtg:delayed = Falsefda = Falseif order.first_dlvyatmp_timestamp.date() < order.delivery_timestamp.date():fda = Truefda_datetime = order.first_dlvyatmp_timestampfda_date = fda_datetime.date()if order.promised_delivery_time.date() < fda_date:delayed = Trueif not delayed and not fda:thank_you_html = """We are pleased to inform that the following items in your order $master_order_id have been delivered.<br/>As Promised order placed by you has been <b>Delivered On Time.</b><br/>If you are happy with our services please join us on <a href="https://twitter.com/saholic">Twitter</a>, <a href="http://www.facebook.com/mysaholic">Facebook Page</a> and help us spread the word.<br/>Delivered Item Details are:"""elif delayed:max_discount = 500*otgCountdelayedDays = max(1,get_business_days_count(order.promised_delivery_time, fda_datetime))max_discount = min(max_discount, totalUnitPrice/10)discount = min(round(max_discount),delayedDays*50*otgCount)promotion_client = PromotionClient().get_client()endOn = order.delivery_timestamp + datetime.timedelta(days = 30)expiry = endOn.strftime("%A, %d. %B %Y")endOn = to_java_date(endOn)arguments = "{\"endOn\":" + str(endOn) + ", \"emails\":[\"" + order.customer_email + "\"], \"couponType\":\"both\", \"usage_limit_for_user\":1, \"isCod\":False, \"discount\":" + str(discount) + "}"otgCoupon = promotion_client.createCoupon(28,CouponCategory.CUSTOMER_SATISFACTION , '', arguments, False, "otg")thank_you_html = """Following items in your order $master_order_id have been delivered. We apologise for a delay of """+str(delayedDays)+""" days<br/>As per our On Time Guarantee Please accept a Gift Voucher worth Rs. """+str(discount)+""" as a token of our apology.Your unique Gift Voucher Code is """+str(otgCoupon)+""" Gift Voucher Expiry Date: """+str(expiry)+"""<br/>You can use the same to buy any Mobile, Camera, Laptop, Tablet, Accessory or Mobile/DTH Recharge from our website.</br/>If you are happy with our services please join us on <a href="https://twitter.com/saholic">Twitter</a>, <a href="http://www.facebook.com/mysaholic">Facebook Page</a> and help us spread the word.<br/>"""elif fda:fdaFormattedString = order.first_dlvyatmp_timestamp.strftime("%A, %d. %B %Y")thank_you_html = """We are pleased to inform that the following items in your order $master_order_id have been delivered.<br/> The First Delivery attempt was made on """+ fdaFormattedString +""" , within our commited estimated time for delivery.<br/>If you are happy with our services please join us on <a href="https://twitter.com/saholic">Twitter</a>, <a href="http://www.facebook.com/mysaholic">Facebook Page</a> and help us spread the word.<br/>Following Items are Delivered:"""else :thank_you_html = """We are pleased to inform that the following items in your order $master_order_id have been delivered.<br/>Following Items are Delivered:"""#If you are happy with our services please join us on <a href="https://twitter.com/saholic">Twitter</a>, <a href="http://www.facebook.com/mysaholic">Facebook Page</a> and help us spread the word.<br/>freebie_text = "<br/>"if hasFreebie and not hasSplitOrder:freebie_text = freebie_text + "We have also delivered your freebies with eligible products as promised<br/>"elif not hasFreebie and hasSplitOrder:freebie_text = freebie_text + "We wish to inform you that your freebie item(s): <br/>"for splitOrder in splitOrdersMap.values():freebieLineItem = get_line_items_for_order(splitOrder.id)[0]freebie_text = freebie_text + freebieLineItem.brand + " " + freebieLineItem.model_name + " " + freebieLineItem.model_number + " will be sent as a separate order with OrderId : " + str(splitOrder.id) + " and is expected to be delivered on " + splitOrder.expected_delivery_time.strftime("%A, %d %B %Y")+ "<br/>"+ "<br/>You can track the status of this order from My Orders section in saholic.com"elif hasFreebie and hasSplitOrder:freebie_text = freebie_text + "We have also delivered some of your freebies with eligible products as promised and rest freebie item(s) details are given below: <br/>"for splitOrder in splitOrdersMap.values():freebieLineItem = get_line_items_for_order(splitOrder.id)[0]freebie_text = freebie_text + freebieLineItem.brand + " " + freebieLineItem.model_name + " " + freebieLineItem.model_number + " will be sent as a separate order with OrderId : " + str(splitOrder.id) + " and is expected to be delivered on " + splitOrder.expected_delivery_time.strftime("%A, %d %B %Y")+ "<br/>" + "<br/>You can track the status of this order from My Orders section in saholic.com"else:freebie_text = ""insuranceText = ""if hasInsurer:insuranceText = "Some item(s) are Insured Against Theft for 1 Year. <a href='http://www.saholic.com/static/insurance-terms'>Know More</a><br/>Please download and read attached policy document."customer_name = order.customer_nameorder_date = order.created_timestampuser_email = order.customer_emailsubject = "{0} - Your shipment {1} is delivered".format(source_name, logisticsTxnId)dt = datetime.datetime.strptime(str(order_date), "%Y-%m-%d %H:%M:%S")formated_order_date = dt.strftime("%A, %d. %B %Y %I:%M%p")complete_html = html_header + thank_you_html + htmlemail_html = Template(complete_html).substitute(dict(master_order_id = logisticsTxnId, order_date = formated_order_date, customer_name = customer_name, pickup_text = pickup_text, source_url = source_url, source_name = source_name, freebie_text = freebie_text, insurance_text = insuranceText))try:helper_client = HelperClient(host_key = "helper_service_server_host_prod").get_client()helper_client.saveUserEmailForSending([user_email], SaholicHelpEmailId, subject, email_html, logisticsTxnId, "DeliverySuccess", [], [], order.source)if order.source == OrderSource.WEBSITE:send_transaction_sms(order.customer_id, order.customer_mobilenumber, "Dear Customer, Your order: " + logisticsTxnId + " has been delivered now. For any queries please call +918826894203." , SmsType.TRANSACTIONAL, True)return Trueexcept Exception as e:print ereturn Falsedef __get_secret_code(order_id):return get_order_attribute_value(order_id, 'SECRET_CODE')def get_order_attribute_value(order_id, attribute_name):existingAttribute = Attribute.query.filter(Attribute.orderId == order_id).filter(Attribute.name == attribute_name).first()if existingAttribute:return existingAttribute.valuereturn ""def change_jacket_number(order_id, jacket_number):order = get_order(order_id)if order.status == OrderStatus.BILLED:order.jacket_number = jacket_numbersession.commit()return Truereturn Falsedef mark_order_as_rto_in_transit(order_id):selectedOrder = get_order(order_id)if selectedOrder.logisticsTransactionId:orders = get_group_orders_by_logistics_txn_id(selectedOrder.logisticsTransactionId)for order in orders:if order == None or order.status not in [OrderStatus.SHIPPED_FROM_WH, OrderStatus.DELIVERED_AT_STORE, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY, OrderStatus.REACHED_DESTINATION_CITY, OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE, OrderStatus.DELIVERY_SUCCESS]:return Falseorder.status = OrderStatus.RTO_IN_TRANSITorder.delivery_timestamp = datetime.datetime.now()order.statusDescription = "Order Returned to Origin"try:alert_client = AlertClient().get_client()alert_client.endMonitoringEntity(EntityType.COURIER, "orderId = " + str(order.id))except Exception as e:print "Exception in ending alert in MarkOrderAsRTO method"print eupdate_trust_level(orders[0])session.commit()else:if selectedOrder == None or selectedOrder.status not in [OrderStatus.SHIPPED_FROM_WH, OrderStatus.DELIVERED_AT_STORE, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY, OrderStatus.REACHED_DESTINATION_CITY, OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE, OrderStatus.DELIVERY_SUCCESS]:return FalseselectedOrder.status = OrderStatus.RTO_IN_TRANSITselectedOrder.delivery_timestamp = datetime.datetime.now()selectedOrder.statusDescription = "Order Returned to Origin"update_trust_level(selectedOrder)session.commit()try:alert_client = AlertClient().get_client()alert_client.endMonitoringEntity(EntityType.COURIER, "orderId = " + str(selectedOrder.id))except Exception as e:print "Exception in ending alert in MarkOrderAsRTO method"print ereturn Truedef get_order(order_id):order = Order.get_by(id=order_id)if not order:print "Not found order for orderId " + str(order_id)raise TransactionServiceException(108, "no such order")return orderdef get_order_list(order_ids):orders = Order.query.filter(Order.id.in_(tuple(order_ids)))return ordersdef get_order_list_for_vendor(order_ids, vendor_id):if vendor_id == -1:return get_order_list(order_ids)else:orders = Order.query.filter_by(vendorId = vendor_id).filter(Order.id.in_(tuple(order_ids)))return ordersdef get_orders_for_customer(customer_id, from_date, to_date, statuses):if not customer_id:raise TransactionServiceException(101, "bad customer id")query = Order.query.filter(Order.customer_id == customer_id)if statuses:query = query.filter(Order.status.in_(tuple(statuses)))if from_date:query = query.filter(Order.created_timestamp >from_date)if to_date:query = query.filter(Order.created_timestamp < to_date)return query.all()def get_order_for_customer(order_id, customer_id):if not customer_id:raise TransactionServiceException(101, "bad customer id")order = get_order(order_id)if order.customer_id != customer_id:raise TransactionServiceException(108, "order: " + str(order_id) + " does not belong to customer: " + str(customer_id))return orderdef get_all_orders(statuses, from_date, to_date, warehouse_id):query = Order.query.options(joinedload('lineitems'))if not len(statuses):query = query.filter(Order.status >= OrderStatus.COD_VERIFICATION_PENDING)else:query = query.filter(Order.status.in_(statuses))if warehouse_id:query = query.filter(Order.warehouse_id == warehouse_id)#raise TransactionServiceException(101, "bad warehouse id")if from_date:if to_date:query = query.filter(or_(and_(Order.created_timestamp >from_date, Order.created_timestamp < to_date),and_(Order.refund_timestamp >from_date, Order.refund_timestamp < to_date)))else:query = query.filter(Order.created_timestamp >from_date)else:if to_date:query = query.filter(or_(Order.created_timestamp < to_date, Order.refund_timestamp < to_date))return query.all()def get_orders_in_batch(statuses=[], offset=0, limit=0, warehouse_id=None, source=0):print "source ------------", sourceprint "statuses ------------", statusesquery = Order.query.options(joinedload('lineitems'))if warehouse_id:query = query.filter(Order.warehouse_id == warehouse_id)if source:query = query.filter(Order.source == source)if statuses:query = query.filter(Order.status.in_(statuses))query = query.offset(offset)if limit:query = query.limit(limit)return query.all()def get_orders_in_batch_as_promised_shipping(statuses=[], offset=0, limit=0, warehouse_id=None, source=0):print "source ------------", sourceprint "statuses ------------", statusesquery = Order.query.options(joinedload('lineitems'))if warehouse_id:query = query.filter(Order.warehouse_id == warehouse_id)if source:query = query.filter(Order.source == source)if statuses:query = query.filter(Order.status.in_(statuses))query = query.order_by(Order.transaction_id)if limit>0:query = query.limit(limit)if offset>0 and limit>0:query = query.offset(offset)return query.all()def get_order_count(statuses=[], warehouse_id=None, source=0):#if not warehouse_id:# raise TransactionServiceException(101, "bad warehouse id")query = session.query(func.count(Order.id))if warehouse_id:query = query.filter(Order.warehouse_id == warehouse_id)if source:query = query.filter(Order.source == source)if statuses:query = query.filter(Order.status.in_(statuses))return query.scalar()def get_returnable_orders_for_customer(customer_id, limit = None):if not customer_id:raise TransactionServiceException(101, "bad customer id")query = Order.query.filter(Order.customer_id == customer_id)query = query.filter(Order.status != OrderStatus.PAYMENT_FAILED)query = query.filter(Order.status != OrderStatus.REJECTED)query = query.filter(Order.status > OrderStatus.SHIPPED_FROM_WH)query = query.filter(or_(Order.status < OrderStatus.DELIVERY_SUCCESS, Order.delivery_timestamp < datetime.datetime.now() + datetime.timedelta(hours = 48)))orders = query.all()order_ids = [order.id for order in orders]return order_idsdef get_cancellable_orders_for_customer(customer_id, limit = None):if not customer_id:raise TransactionServiceException(101, "bad customer id")cancellableOrderStatuses = OrderStatusGroups().codCancellablequery = Order.query.filter(Order.customer_id == customer_id)query = query.filter(Order.status.in_(cancellableOrderStatuses))orders = query.all()return [order.id for order in orders]def get_orders_by_billing_date(status, start_billing_date, end_billing_date, warehouse_id):if not warehouse_id:raise TransactionServiceException(101, "bad warehouse id")query = Order.query.filter(Order.warehouse_id == warehouse_id)if status:query = query.filter(Order.status == status)if start_billing_date:query = query.filter(Order.billing_timestamp >= start_billing_date)if end_billing_date:query = query.filter(Order.billing_timestamp <= end_billing_date)return query.all()def get_orders_by_shipping_date(from_shipping_date, to_shipping_date, provider_id, warehouse_id, cod):query = Order.query.filter(Order.cod == cod)if warehouse_id and warehouse_id != -1:query = query.filter(Order.warehouse_id == warehouse_id)if provider_id and provider_id != -1:query = query.filter(Order.logistics_provider_id == provider_id)if from_shipping_date:query = query.filter(Order.shipping_timestamp >= from_shipping_date)if to_shipping_date:query = query.filter(Order.shipping_timestamp <= to_shipping_date)query = query.order_by(Order.airwaybill_no)return query.all()def get_orders_for_transaction(transaction_id, customer_id):orders = Order.query.filter_by(transaction_id=transaction_id, customer_id=customer_id).all()if not orders:raise TransactionServiceException(101, "No order for the transaction")return ordersdef get_undelivered_orders(provider_id, warehouse_id):query = Order.queryif provider_id != -1:query = query.filter_by(Order.logistics_provider_id == provider_id)if warehouse_id != -1:query = query.filter(Order.warehouse_id == warehouse_id)query = query.filter(and_(Order.status != OrderStatus.DELIVERY_SUCCESS, Order.status != OrderStatus.FAILED, \Order.status > OrderStatus.SHIPPED_FROM_WH))#Get last midnight time instead of current time as courier company would have sent the#delivery records updated at least till midnight and not by the current time.time_format = "%Y-%m-%d %H:%M:%S.%f"t = time.strptime(str(datetime.datetime.now()), time_format)midnightTime = datetime.datetime(*t[:3])query = query.filter(Order.expected_delivery_time < midnightTime)orders = query.all()return ordersdef get_line_items_for_order(order_id):query = LineItem.query.filter(LineItem.order_id == order_id)return query.all()def change_order_status(self, orderId, status, description):order = get_order(orderId)order.status = statusorder.statusDescription = descriptionsession.commit()update_trust_level(order)return Truedef update_trust_level(order):try:trust_level_delta = 0if order.cod == True:if order.status in [OrderStatus.RTO_RESHIPPED] and order.logisticsTransactionId:earlierMarkedReshipped = Order.query.filter(Order.logisticsTransactionId == order.logisticsTransactionId).filter(Order.status==OrderStatus.RTO_RESHIPPED).first()if earlierMarkedReshipped is None:trust_level_delta = ORDER_STATUS_TO_USER_TRUST_LEVEL_DELTA_DICT.get(order.status, 0)else:trust_level_delta = ORDER_STATUS_TO_USER_TRUST_LEVEL_DELTA_DICT.get(order.status, 0)if (trust_level_delta != 0):user_client = UserClient().get_client()user_client.increaseTrustLevel(order.customer_id, trust_level_delta)except Exception as e:print ereturn Truedef verify_order(orderId):logging.info("Verifying order no: " + str(orderId))order = get_order(orderId)if order.status == OrderStatus.COD_VERIFICATION_PENDING:order.status = OrderStatus.SUBMITTED_FOR_PROCESSINGorder.statusDescription = "Submitted for processing"order.verification_timestamp = datetime.datetime.now()session.commit()if order.source == OrderSource.STORE:sod = StoreOrderDetail.get_by(orderId = order.id)__push_store_collection_to_hotspot(order, "advance", sod.cashAmount, sod.cardAmount)logging.info("Successfully verified order no: " + str(orderId))return Trueelse:logging.warning("Verify called for order no." + str(orderId) +" which is not in verification pending state");return Falsedef unaccept_order(orderId):logging.info("UnAccepting order no: " + str(orderId))order = get_order(orderId)if order.status != OrderStatus.ACCEPTED:return FalselogisticsTxnId = order.logisticsTransactionIdorders = [order]if logisticsTxnId is not None:orders = Order.query.filter(Order.logisticsTransactionId==logisticsTxnId).all()for o in orders:o.status = OrderStatus.SUBMITTED_FOR_PROCESSINGo.statusDescription = 'Submitted For Processing'o.accepted_timestamp = Noneo.logisticsTransactionId = Noneo.airwaybill_no = Noneo.tracking_id = Noneo.billing_timestamp = Noneo.invoice_number= Noneo.jacket_number = Noneo.refund_timestamp= Noneo.refunded_by= Noneo.refund_reason= Nonesession.commit()return Truedef __capture_txn(txnId):logging.info("Capturing payment for merchant txn:" + str(txnId))captured_amount = 0try:payment_client = PaymentClient().get_client()payments = payment_client.getPaymentForTxnId(txnId)for payment in payments:if payment.gatewayId in (gvGatewayId, walletGatewayId):continuecapture_result = payment_client.capturePayment(txnId, False)if capture_result:captured_amount = captured_amount + payment.amountlogging.info("Successfully captured payment for merchant txn:" + str(txnId))#change_transaction_status(txnId, TransactionStatus.IN_PROCESS, "Payment received", PickUpType.COURIER, order.orderType, order.source)else:raise TransactionServiceException(115, "Payment capture failed.")return captured_amountexcept PaymentException as e:if e.error_code == 106:#order.status = OrderStatus.CAPTURE_IN_PROCESS#session.commit()raise TransactionServiceException(122, "Unable to capture payment due to connection issue.")else:raise TransactionServiceException(115, "Payment capture failed.")def __amend_fulfilment_warehouse(order):itemId = order.lineitems[0].item_idinventoryClient = InventoryClient().get_client()inventory = inventoryClient.getItemInventoryByItemId(itemId)if not (inventory.availability.has_key(order.fulfilmentWarehouseId) and inventory.availability[order.fulfilmentWarehouseId]):for warehouse in inventoryClient.getWarehouses(WarehouseType.OURS, InventoryType.GOOD, 0, order.warehouse_id, 0):if inventory.availability.has_key(warehouse.id) and inventory.availability[warehouse.id] >= inventory.reserved[warehouse.id] + order.lineitems[0].quantity:inventoryClient.reduceReservationCount(itemId, order.fulfilmentWarehouseId, sourceId, order.id, order.lineitems[0].quantity)inventoryClient.reserveItemInWarehouse(itemId, warehouse.id, sourceId, order.id, to_java_date(order.created_timestamp), to_java_date(order.promised_shipping_time), order.lineitems[0].quantity)order.fulfilmentWarehouseId = warehouse.idbreakdef __isFreebieOrderBillable(order):parentOrderId = get_order_attribute_value(order.id, "parentOrderIdForFreebie")parentOrder = Order.get_by(id = parentOrderId)if parentOrder.cod and parentOrder.status!=12:return Falseelse:return Truedef __getOrderTaxType(order, state='Delhi'):return TaxType.SGST if state == order.customer_state else TaxType.IGST# delhiPincodePrefix = "11";# maharashtraPincodePrefix = ["40", "41", "42", "43", "44"];# karnatakaPincodePrefix = ["56", "57", "58", "59"];# telenganaPincodes = ["500001","500002","500003","500004","500005","500006","500007","500008","500009","500010","500011","500012","500013","500014","500015","500016","500017","500018","500019","500020","500021","500022","500023","500024","500025","500026","500027","500028","500029","500030","500031","500032","500033","500034","500035","500036","500037","500038","500039","500040","500041","500042","500043","500044","500045","500046","500047","500048","500049","500050","500051","500052","500053","500054","500055","500056","500057","500058","500059","500060","500061","500062","500063","500064","500065","500066","500067","500068","500069","500070","500071","500072","500073","500074","500075","500076","500077","500078","500079","500080","500081","500082","500083","500084","500085","500086","500087","500088","500089","500090","500091","500092","500093","500094","500095","500096","500097","500098","500178","500409","501218","501301","501401","501510","501511","501512","502307","502319","517501","517502","517503","517505","517507","520001","520002","520003","520004","520005","520006","520007","520008","520009","520010","520011","520012","520013","520014","520015","521108","521225","522001","522002","522003","522004","522005","522006","522007","522019","522509","530001","530002","530003","530004","530005","530007","530008","530009","530010","530010","530011","530012","530013","530014","530015","530016","530017","530018","530020","530021","530022","530023","530024","530026","530027","530028","530029","530032","530035","530040","530041","530043","530044","530045","530046","531001","533101","533103","533104","533105"]# haryanaPincodes = ["133001","134003","123307","133205","125047","122005","131104","132111","121001","132038","134002","124411","132039","124505","124021","124521","132122","121105","133301","125021","132154","133005","123308","124105","125048","122101","124507","125028","131021","123413","124142","124110","125054"# ,"134007","124416","121004","132040","126145","125061","125026","125078","133201","124101","124304","125045","134118","126010","126011","125042","123025","123501","125032","123034","132108","124201","124409","124401","124503","131022","125053","124415","122102","135106","126008","124310","132140","133101","135102","123026","125022","133021","135101","124302","134107","125027","123306","125101","135103","124504","132034","171208","124542","122002","126153","125036","125025","124109","124424","132020","123412","125106","122106","132112","133202","124107","125058","124202","124202","124528","125102","121007","121001","121002","121005","121006","124408","123506","125050","132042","122104","122001","131101","123505","132114","124301","125103","132035","125001","123504","124423","125033","124404","121107","121103","132115","125004","125011","125002","121106","134109","132041","122016","132129","132107","124103","126102","135003","135002","126001","131023","124535","124314","134201","132130","123310","131024","125030","126101","132036","132001","132118","132025","124412","125085","125029","132027","124113","143512","125201","133105","126117","126133","133302","124530","123027","132021","133102","125057","123502","125038","124305","124114","124402","135105","135021","123103","123101","124144","123102","131028","132022","132119","132132","124514","124108","132037","124111","132113","124203","125052","123021","125104","125056","124506","125105","123309","124510","124106","124112","125005","125088","123029","124022","134205","133203","125041","124306","131027","133103","123001","122108","124145","131103","125037","125039","134012","123023","123028","123414","134203","126116","132106","132145","124104","124513","124531","132117","132024","122107","125077","131029","132103","126007","123035","132043","124417","121102","132104","132105","134011","123503","125003","176050","132128","132128","124205","126113","134102","134101","132131","132026","121104","131102","124001","132133","134204","132044","151301","126110","125076","131030","125051","123401","125067","124429","125043","124403","125055","131001","133204","126112","133104","124146","132023","132046","132101","124501","124303","123020","133206","123024","125044","132033","125046","132135","176206","134202","126114","125060","125049","124407","124430","122103","125075","132153","132116","122105","132136","121101","125031","126119","125040","126115","132124","133207","126009","125083","132137","124406"]## #Simplify either its IGST or SGST# if state == WarehouseLocation.Delhi:# if order.customer_pincode.startswith(delhiPincodePrefix):# return TaxType.SGST# else:# return TaxType.IGST# #Maharashta# if state == WarehouseLocation.Mumbai:# for mahaPincodePrefix in maharashtraPincodePrefix:# if order.customer_pincode.startswith(mahaPincodePrefix):# return TaxType.SGST# return TaxType.IGST# if state == WarehouseLocation.Karnataka:# for knkPincodePrefix in karnatakaPincodePrefix:# if order.customer_pincode.startswith(knkPincodePrefix):# return TaxType.SGST# return 1# if state == WarehouseLocation.Telangana:# if order.customer_pincode in telenganaPincodes:# return TaxType.SGST# return TaxType.IGST# if state == WarehouseLocation.Haryana:# if order.customer_pincode in haryanaPincodes:# return TaxType.SGST# return TaxType.IGST# return TaxType.SGSTdef add_billing_details(orderId, invoice_number, serialNumbers, itemNumbers, freebieWarehouseId, billedBy, jacketNumber, billingType, fulfilmentWarehouseId, authorize):if billedBy is None or billedBy.strip() == "":raise TransactionServiceException(110, "Invalid Biller")order = Order.get_by(id=orderId)hsnCode = order.lineitems[0].hsnCodeif not order:raise TransactionServiceException(101, "No order found for the given order id" + str(orderId))newTaxType = __getOrderTaxType(order)order.taxType = newTaxTypeif jacketNumber is None or jacketNumber <= 0:if order.source == OrderSource.EBAY or order.source == OrderSource.SNAPDEAL or order.source == OrderSource.FLIPKART:print "Skipping Jacket Number field for OrderId " + str(orderId)else:raise TransactionServiceException(110, "Invalid jacket number")'''First checking whether freebie can be billed or not otherwise wont proceed.'''if order.freebieItemId:if billingType == BillingType.OURS or billingType == BillingType.OURS_EXTERNAL:if freebieWarehouseId:try:inventory_client = InventoryClient().get_client()warehouse = inventory_client.getWarehouse(freebieWarehouseId)if warehouse.warehouseType!= WarehouseType.OURS or warehouse.inventoryType != InventoryType.GOOD:raise TransactionServiceException(110,'Billing of Freebie is only allowed from OURS_GOOD warehouses ')warehouse_client = WarehouseClient().get_client()isItemAvailable = warehouse_client.isItemAvailableForSale(order.freebieItemId, "", freebieWarehouseId)if isItemAvailable == False:raise TransactionServiceException(110,'No Freebie Item available ')except Exception as e:print e.messageraise TransactionServiceException(110,'Error in billing freebie for warehouseId ' + str(freebieWarehouseId))else:raise TransactionServiceException(110,'No warehouseId provided for billing of freebie ')else:raise TransactionServiceException(110,'Order with freebies associated with it cant be billed from an external warehouse ')lineitem = order.lineitems[0]item_id = lineitem.item_id'''Checking if order is a freebie split-order and if the order is cod and if the original order is marked as delivered.'''freebie_order_info_text = "Freebie Order for Order ID"if lineitem.extra_info and freebie_order_info_text in lineitem.extra_info:canbillOrder = __isFreebieOrderBillable(order)if canbillOrder == False:raise TransactionServiceException(110,'Parent order for this is COD and is still undelivered')# inventoryClient = InventoryClient().get_client()# if not inventoryClient.isOrderBillable(item_id, order.fulfilmentWarehouseId, sourceId, orderId):# raise TransactionServiceException(101, "There are other orders to be billed before this order id " + str(orderId))singleInvoiceAttr = Attribute.query.filter(Attribute.orderId == order.id).filter(Attribute.name == "Single Invoice").first()catalog_client = CatalogClient().get_client()item = catalog_client.getItem(item_id)if order.status == OrderStatus.ACCEPTED:order.jacket_number = jacketNumberif itemNumbers:lineitem.item_number = itemNumbers[0]if serialNumbers:lineitem.serial_number = serialNumbers[0]if order.productCondition == ProductCondition.BAD:if billingType != BillingType.OURS:raise TransactionServiceException(110, 'Bad inventory is not allowed to be sold from current warehouse')if billingType == BillingType.EXTERNAL:order.invoice_number = invoice_numberif billingType == BillingType.OURS or billingType == BillingType.OURS_EXTERNAL:if ItemType.SERIALIZED == item.type and not (serialNumbers and serialNumbers[0]):raise TransactionServiceException(110, "No Serial Number supplied")if singleInvoiceAttr:if singleInvoiceAttr.value == "true":if serialNumbers:finalSerialNo =''for serialNumber in serialNumbers:finalSerialNo = finalSerialNo +','+ serialNumberfinalSerialNo = finalSerialNo[1:]if lineitem.serial_number is None:lineitem.serial_number = finalSerialNoelse:if serialNumbers:lineitem.serial_number = serialNumbers[0]order.status = OrderStatus.BILLEDorder.statusDescription = "Order Billed"order.billing_timestamp = datetime.datetime.now()order.billed_by = billedBy#Manish Sharma InvoicewhStateId = None# Letting the billing process fail in cases where we are unable to# fill in transfer pricetry:inventory_client = InventoryClient().get_client()warehouse = inventory_client.getWarehouse(fulfilmentWarehouseId)item_pricing = inventory_client.getItemPricing(item_id, warehouse.vendor.id)lineitem.transfer_price = item_pricing.transferPricelineitem.nlc = item_pricing.nlcexcept InventoryServiceException as e:print sys.exc_info()[0]print e.messageraise TransactionServiceException(110, 'Transfer price missing for itemId: ' + str(item_id) + ' and vendor: ' + str(warehouse.vendor.id))# For OUR warehouse, we need to scan out items for every billed orderif billingType == BillingType.OURS:if order.productCondition == ProductCondition.GOOD:for index, serialNumber in enumerate(serialNumbers):try:warehouse_client = WarehouseClient().get_client()# Fetching GOOD w/h corresponding to the virtual one hereif not warehouse.billingWarehouseId:warehouse = inventory_client.getWarehouses(None, InventoryType.GOOD, warehouse.vendor.id, order.warehouse_id, 0)[0]if ItemType.SERIALIZED == item.type:inventoryItem = warehouse_client.getInventoryItem(serialNumber)else:inventoryItem = warehouse_client.getNonSeralizedInventoryItem(itemNumbers[index], item_id, warehouse.id, warehouse.billingWarehouseId)if (inventoryItem.itemId != item_id):catalog_client = CatalogClient().get_client()item = catalog_client.getItem(inventoryItem.itemId)scanItemString = " ".join([str(item.brand), str(item.modelName), str(item.modelNumber), str(item.color)])lineItemString = " ".join([str(lineitem.brand), str(lineitem.model_name), str(lineitem.model_number), str(lineitem.color)])raise TransactionServiceException(110, 'Trying to scan ' + scanItemString + ' instead of ' + lineItemString)if ItemType.SERIALIZED == item.type:inventoryItem = warehouse_client.scanSerializedItemForOrder(serialNumber, ScanType.SALE, orderId, warehouse.id, 1, order.warehouse_id)else:inventoryItem = warehouse_client.scanForOrder(inventoryItem, ScanType.SALE, 1, order.id, warehouse.id, order.warehouse_id)lineitem.transfer_price = inventoryItem.unitPricelineitem.nlc = inventoryItem.nlcorder.vendorId = inventoryItem.supplierIdcatalog_client = CatalogClient().get_client()except WarehouseServiceException as e:print sys.exc_info()[0]print 'Could not scan out orders due to: ' + e.messageraise TransactionServiceException(110, e.message)else:for index, serialNumber in enumerate(serialNumbers):try:warehouse_client = WarehouseClient().get_client()if ItemType.SERIALIZED == item.type:inventoryItem = warehouse_client.scanForBadSale(serialNumber, itemNumbers[index], item_id, orderId, warehouse.id, 1, order.warehouse_id)else:inventoryItem = warehouse_client.scanForBadSale(serialNumber, itemNumbers[index], item_id, orderId, warehouse.id, lineitem.quantity, order.warehouse_id)lineitem.transfer_price = inventoryItem.unitPricelineitem.nlc = inventoryItem.nlcorder.vendorId = inventoryItem.supplierIdcatalog_client = CatalogClient().get_client()except WarehouseServiceException as e:print sys.exc_info()[0]print 'Could not scan out orders due to: ' + e.messageraise TransactionServiceException(110, e.message)elif billingType == BillingType.OURS_EXTERNAL:try:if ItemType.SERIALIZED == item.type:serialNumber = serialNumbers[0]else:serialNumber = ""warehouse_client = WarehouseClient().get_client()inventoryItem = warehouse_client.scanForOursExternalSale(lineitem.item_id, serialNumber, lineitem.item_number, invoice_number, order.fulfilmentWarehouseId, lineitem.transfer_price, lineitem.nlc, order.id)lineitem.transfer_price = inventoryItem.unitPricelineitem.nlc = inventoryItem.nlcorder.vendorId = inventoryItem.supplierIdexcept WarehouseServiceException as e:print sys.exc_info()[0]print 'Could not scan out orders due to: ' + e.messageraise TransactionServiceException(110, e.message)else:if not warehouse.isAvailabilityMonitored:inventory_client = InventoryClient().get_client()inventory_client.addInventory(item.id, warehouse.id, -1 * lineitem.quantity)if order.freebieItemId:try:inventory_client = InventoryClient().get_client()freebie_warehouse = inventory_client.getWarehouse(freebieWarehouseId)if freebie_warehouse.warehouseType!= WarehouseType.OURS or freebie_warehouse.inventoryType != InventoryType.GOOD:raise TransactionServiceException(110,'Billing of Freebie is only allowed from OURS_GOOD warehouses ')warehouse_client = WarehouseClient().get_client()inventoryItem = warehouse_client.scanfreebie(orderId, order.freebieItemId, freebieWarehouseId, ScanType.SALE);attr = Attribute()attr.orderId = orderIdattr.name = "freebie_tp"attr.value = str(inventoryItem.unitPrice)attr1 = Attribute()attr1.orderId = orderIdattr1.name = "freebie_vendor"attr1.value = str(inventoryItem.supplierId)attr2 = Attribute()attr2.orderId = orderIdattr2.name = "freebie_nlc"attr2.value = str(inventoryItem.nlc)except Exception as e:print e.messageraise TransactionServiceException(110,'Error in billing freebie for warehouseId ' + str(freebieWarehouseId))if order.productCondition != ProductCondition.BAD:__update_inventory_reservation(order)order.fulfilmentWarehouseId = warehouse.idif singleInvoiceAttr:if singleInvoiceAttr.value == "true":session.commit()return Trueif billingType == BillingType.OURS or billingType == BillingType.OURS_EXTERNAL:#as of now only company 2 - SORPL, 3-New company is operating and cutoff config will decide the company to be used to bill#until further change - Amit Guptaseller_id = __get_seller(order.warehouse_id)order.invoice_number = get_next_invoice_counter(seller_id, order.warehouse_id, hsnCode)order.seller_id = seller_idwhaddressmapping = WarehouseAddressMapping.query.filter_by(warehouse_id=order.warehouse_id).one()order.warehouse_address_id = whaddressmapping.address_idsession.commit()return Trueelse:return Falsedef add_invoice_number(orderId, invoiceNumber, color, serialNumber, itemNumber):order = Order.get_by(id=orderId)if not order:raise TransactionServiceException(101, "No order found for the given order id" + str(orderId))if order.status == OrderStatus.ACCEPTED:order.invoice_number = invoiceNumberif color:billedOrdersColorMap[orderId] = colorif serialNumber:order.lineitems[0].serial_number = serialNumber.strip()if itemNumber:order.lineitems[0].item_number = itemNumber.strip()session.commit()def batch_orders(warehouseId):if not warehouseId:raise TransactionServiceException(101, "bad warehouse id")batchno_generator = BatchNoGenerator()session.commit()query = Order.query.filter_by(warehouse_id=warehouseId)query = query.filter(Order.status == OrderStatus.LOW_INV_PO_RAISED)query = query.order_by(Order.created_timestamp)pending_orders = query.all()serial_no = 1for order in pending_orders:order.batchNo = batchno_generator.idorder.serialNo = serial_noserial_no += 1session.commit()pending_orders = query.all()return pending_ordersdef order_outofstock(orderId):'''Mark order as out of stock'''order = get_order(orderId)order.status = OrderStatus.INVENTORY_LOWorder.statusDescription = "Low Inventory"order.outofstock_timestamp = datetime.datetime.now()session.commit()return Truedef mark_orders_as_shipped_from_warehouse(warehouseId, providerId, cod, orderIds):try:current_timestamp = datetime.datetime.now()orders = Order.query.filter(Order.id.in_(orderIds)).filter_by(warehouse_id = warehouseId, logistics_provider_id = providerId, status = OrderStatus.BILLED).all()for order in orders:order.status = OrderStatus.SHIPPED_FROM_WHorder.statusDescription = "Order shipped from warehouse"order.shipping_timestamp = current_timestamp'''try:print "Trying to schedule alert"monitoredEntity = MonitoredEntity();monitoredEntity.entityType=EntityType.COURIER;monitoredEntity.eventType=OrderStatus.SHIPPED_FROM_WH;monitoredEntity.entityIdentifier="orderId = " + str(order.id);adjustedDeliveryDays = adjust_delivery_time(datetime.datetime.now(), 1);sec = datetime.datetime.now()#Warn alert time is taken as 16 hrswarn_time = (sec + timedelta(days=(adjustedDeliveryDays-1)) + timedelta(hours=16))#Critical alert time is taken as 26 hrscritical_time = (sec + timedelta(days=(adjustedDeliveryDays-1)) + timedelta(hours=26))monitoredEntity.warnExpiryTime = int(warn_time.strftime("%s"))*1000monitoredEntity.criticalExpiryTime = int(critical_time.strftime("%s"))*1000monitoredEntity.description="warehouseId = " + str(warehouseId) + " providerId = " + str(providerId) + " orderId = " + str(order.id);alert_client = AlertClient().get_client()alert_client.scheduleAlert(monitoredEntity)except Exception as e:print "Exception in scheduling alert in ShippedFromWarehouse method"print e'''session.commit()logisticsTxnIdOrdersMap = {}for order in orders:if order.logisticsTransactionId:if logisticsTxnIdOrdersMap.has_key(order.logisticsTransactionId):ordersList = logisticsTxnIdOrdersMap.get(order.logisticsTransactionId)ordersList.append(order)logisticsTxnIdOrdersMap[order.logisticsTransactionId] = ordersListelse:ordersList = []ordersList.append(order)logisticsTxnIdOrdersMap[order.logisticsTransactionId] = ordersListelse:ordersList = []ordersList.append(order)logisticsTxnIdOrdersMap[str(order.id)] = ordersListfor logisticsTxnId, orderList in logisticsTxnIdOrdersMap.iteritems():enqueue_shipping_confirmation_email(logisticsTxnId, orderList)try:for order in orders:if order.pickupStoreId:send_mails_to_bdms(order)'''else:enqueue_shipping_confirmation_email(order)'''except Exception as e:print ereturn Trueexcept:return Falsedef send_mails_to_bdms(order):logistics_client = LogisticsClient().get_client()store = logistics_client.getPickupStore(order.pickupStoreId)provider = logistics_client.getProvider(order.logistics_provider_id)subject = source_name + " order " + str(order.id) +" shipped to store"raw_message = '''Dear Sir,Order mentioned below is being shipped to your store. Customer will pick it from your store.Store Id: %(store_id)sOrder Id: %(order_id)sProduct: %(product)sDelivery By: %(provider)sPayment Mode: %(payMode)s%(note)sThanks and RegardsHimanshu Pandey'''payMode = 'Prepaid'note = ''if order.cod:payMode = 'COD'note = 'Note: Please collect Rs. ' + str(order.total_amount-order.gvAmount) + ' from customer'message = dedent(raw_message) % { 'order_id' : str(order.id),'store_id' : str(store.hotspotId),'provider' : provider.name,'product' : str(order.lineitems[0]),'payMode' : payMode,'note' : note}to_addresses = [store.email, store.bdmEmail, 'himanshu.pandey@shop2020.in', 'amit.sirohi@shop2020.in', 'ritesh.chauhan@shop2020.in']cc = ['khushal.bhatia@spiceretail.co.in']bcc = ['rajneesh.arora@spiceretail.co.in']mail(mail_user, mail_password, to_addresses, subject, message, [], cc, bcc)def mark_orders_as_returned_from_store(providerId, orderIds, awbs):try:current_timestamp = datetime.datetime.now()orders = Order.query.filter(Order.id.in_(orderIds)).filter_by(logistics_provider_id = providerId, status = OrderStatus.RET_PICKUP_REQUEST_RAISED).all()for order in orders:order.status = OrderStatus.RTO_IN_TRANSITorder.statusDescription = "Order returned from store"order.doa_pickup_timestamp = current_timestamp#order.airwaybill_no = awbs[orderIds.index(order.id)]order.tracking_id = awbs[orderIds.index(order.id)]session.commit()return Trueexcept:return Falsedef set_order_attributes(orderId, attributes):for attribute in attributes :existingAttribute = Attribute.query.filter(Attribute.orderId == orderId).filter(Attribute.name == attribute.name).first()if existingAttribute:existingAttribute.value = attribute.valueelse :attr = Attribute()attr.orderId = orderIdattr.name = attribute.nameattr.value = attribute.valuesession.commit()def mark_orders_as_picked_up(provider_id, pickup_details):for awb, pickup_timestamp in pickup_details.iteritems():orders = []orders = Order.query.filter_by(airwaybill_no=awb, logistics_provider_id = provider_id).all()if orders == None or len(orders) ==0:continuefor order in orders:if order.status != OrderStatus.SHIPPED_FROM_WH:continueorder.status = OrderStatus.SHIPPED_TO_LOGSTorder.statusDescription = "Order picked up by Courier Company"order.pickup_timestamp = pickup_timestamptry:monitoredEntity = MonitoredEntity();monitoredEntity.entityType=EntityType.COURIER;monitoredEntity.eventType=OrderStatus.SHIPPED_TO_LOGSTmonitoredEntity.entityIdentifier="orderId = " + str(order.id);adjustedDeliveryDays = adjust_delivery_time(datetime.datetime.now(), 2);sec = datetime.datetime.now()#Warn alert time is taken as 26 hrswarn_time = (sec + timedelta(days=(adjustedDeliveryDays-2)) + timedelta(hours=26))#Critical alert time is taken as 36 hrscritical_time = (sec + timedelta(days=(adjustedDeliveryDays-1)) + timedelta(hours=36))monitoredEntity.warnExpiryTime = int(warn_time.strftime("%s"))*1000monitoredEntity.criticalExpiryTime = int(critical_time.strftime("%s"))*1000monitoredEntity.description="providerId = " + str(provider_id)alert_client = AlertClient().get_client()alert_client.updateMonitoredObject(monitoredEntity)except Exception as e:print "Exception in updating alert in MarkOrdersAsPickedUp method"print esession.commit()def get_orders_not_picked_up(provider_id):current_time = datetime.datetime.now()to_datetime = datetime.datetime(current_time.year, current_time.month, current_time.day)orders_not_picked_up = Order.query.filter_by(logistics_provider_id = provider_id).filter_by(status=OrderStatus.SHIPPED_FROM_WH).filter(Order.shipping_timestamp <= to_datetime).all()return orders_not_picked_updef mark_orders_as_delivered(provider_id, delivered_orders):logisticsTxnIdOrdersMap = {}for awb, detail in delivered_orders.iteritems():orders = []orders = Order.query.filter_by(airwaybill_no=awb, logistics_provider_id = provider_id).all()if orders == None or len(orders) ==0:continuefor order in orders:if order == None or order.status not in [OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY, OrderStatus.REACHED_DESTINATION_CITY, OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE]:continueif order.logisticsTransactionId:if logisticsTxnIdOrdersMap.has_key(order.logisticsTransactionId):orderList = logisticsTxnIdOrdersMap.get(order.logisticsTransactionId)orderList.append(order)logisticsTxnIdOrdersMap[order.logisticsTransactionId] = orderListelse:orderList =[]orderList.append(order)logisticsTxnIdOrdersMap[order.logisticsTransactionId] = orderListelse:orderList =[]orderList.append(order)logisticsTxnIdOrdersMap[str(order.id)] = orderListtimestamp, receiver = detail.split('|')order.delivery_timestamp = datetime.datetime.strptime(timestamp, "%Y-%m-%d %H:%M:%S")if order.first_dlvyatmp_timestamp is None:order.first_dlvyatmp_timestamp = order.delivery_timestamporder.receiver = receiverif order.pickupStoreId:order.status = OrderStatus.DELIVERED_AT_STOREorder.statusDescription = "Order delivered At Store"try:monitoredEntity = MonitoredEntity();monitoredEntity.entityType=EntityType.COURIER;monitoredEntity.eventType=OrderStatus.DELIVERED_AT_STORE;monitoredEntity.entityIdentifier="orderId = " + str(order.id);#adjustedDeliveryDays = adjust_delivery_time(datetime.datetime.now(), 1);sec = datetime.datetime.now()#Critical alert time is taken as 26 hrscritical_time = (sec + timedelta(hours=4))monitoredEntity.criticalExpiryTime = int(critical_time.strftime("%s"))*1000monitoredEntity.description="deliveryTimeAtStore = " + str(order.delivery_timestamp) + " orderId = " + str(order.id);alert_client = AlertClient().get_client()alert_client.updateMonitoredObject(monitoredEntity)except Exception as e:print eelse:order.status = OrderStatus.DELIVERY_SUCCESSorder.statusDescription = "Order delivered"if order.insuranceDetails:try:update_insurance_details(order)except:print "Error generating insurance file for order " + str(order.id)session.rollback()returnif order.dataInsuranceDetails:order.dataInsuranceDetails[0].startDate = order.delivery_timestamporder.dataInsuranceDetails[0].expiryDate = order.delivery_timestamp + timedelta(days = 90)try:alert_client = AlertClient().get_client()alert_client.endMonitoringEntity(EntityType.COURIER, "orderId = " + str(order.id))except Exception as e:print "Exception in scheduling alert in ShippedFromWarehouse method"print efor logisticsTxnId, ordersList in logisticsTxnIdOrdersMap.iteritems():if enqueue_delivery_success_mail(logisticsTxnId, ordersList) :order = ordersList[0]update_trust_level(order)if order.transaction.payment_option == capitalFloatPayMethod:total_amount = 0for ordObj in ordersList:total_amount = total_amount + ordObj.total_amount + ordObj.shippingCost - ordObj.gvAmountcreditObj = __creditHistoryObj(order.customer_id, 1, order.transaction.id, total_amount, CreditTxnType.LOAN, order.logisticsTransactionId)creditTxns = []creditTxns.append(creditObj)try:process_credit_transaction(order.transaction.id, order.customer_id, 1, creditTxns, order.invoice_number)except:traceback.print_exc()session.rollback()returnelse :session.rollback()session.commit()def update_insurance_details(order):order.insuranceDetails[0].startDate = order.delivery_timestamporder.insuranceDetails[0].expiryDate = order.delivery_timestamp + timedelta(days = 365)filename = "/tmp/" + str(order.id) + "-insurance-policy.pdf"__generate_policy_doc(order, filename)file = open(filename, "rb")pdfFile = file.read()doc = DocumentStore()doc.docType = 1doc.docSource = order.iddoc.document = pdfFiledef mark_order_as_delivered(orderId, deliveryTimestamp, receiver):singleOrder = Order.get_by(id=orderId)logisticsTxnIdOrdersMap = {}grouppedOrdersList = []if singleOrder.logisticsTransactionId:grouppedOrdersList = get_group_orders_by_logistics_txn_id(singleOrder.logisticsTransactionId)for order in grouppedOrdersList:if logisticsTxnIdOrdersMap.has_key(order.logisticsTransactionId):orderList = logisticsTxnIdOrdersMap.get(order.logisticsTransactionId)orderList.append(order)logisticsTxnIdOrdersMap[order.logisticsTransactionId]= orderListelse:orderList=[]orderList.append(order)logisticsTxnIdOrdersMap[order.logisticsTransactionId]= orderListelse:grouppedOrdersList.append(singleOrder)logisticsTxnIdOrdersMap[str(singleOrder.id)]= grouppedOrdersListfor logisticsTxnId, ordersList in logisticsTxnIdOrdersMap.iteritems():order = ordersList[0]if order.transaction.payment_option == capitalFloatPayMethod:total_amount = 0for ordObj in ordersList:total_amount = total_amount + ordObj.total_amount + ordObj.shippingCost - ordObj.gvAmountcreditObj = __creditHistoryObj(order.customer_id, 1, order.transaction.id, total_amount, CreditTxnType.LOAN, order.logisticsTransactionId)creditTxns = []creditTxns.append(creditObj)try:process_credit_transaction(order.transaction.id, order.customer_id, 1, creditTxns, order.invoice_number)except:traceback.print_exc()session.rollback()returnitemIds = []ordersMap = {}orderItemsMap = {}for order in grouppedOrdersList:if order.lineitems[0].item_id not in itemIds:itemIds.append(order.lineitems[0].item_id)ordersMap[order.id] = orderorderItemsMap[order.id] = order.lineitems[0].item_idfor order in grouppedOrdersList:if order == None or order.status not in [OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY, OrderStatus.REACHED_DESTINATION_CITY, OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE, OrderStatus.DOA_PICKUP_REQUEST_RAISED, OrderStatus.DOA_PICKUP_CONFIRMED, OrderStatus.RET_REQUEST_RECEIVED, OrderStatus.RET_PICKUP_CONFIRMED, OrderStatus.RET_REQUEST_AUTHORIZED, OrderStatus.RET_PICKUP_REQUEST_RAISED, OrderStatus.RTO_IN_TRANSIT, OrderStatus.BILLED, OrderStatus.RECEIVED_AT_STORE]:raise TransactionServiceException(101, "Either wrong order id or invalid state " + str(orderId))# Provider is 4 is for self pickup and hardcoded. We should figure out a way to not to hard code.if order.status == OrderStatus.BILLED and order.logistics_provider_id != 4:raise TransactionServiceException(101, "Order is not marked for self pickup: " + str(orderId))if order.status in [OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY, OrderStatus.REACHED_DESTINATION_CITY, OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE, OrderStatus.RTO_IN_TRANSIT, OrderStatus.BILLED, OrderStatus.RECEIVED_AT_STORE]:order.delivery_timestamp = deliveryTimestampif order.first_dlvyatmp_timestamp is None:order.first_dlvyatmp_timestamp = deliveryTimestamporder.receiver = receiverorder.status = OrderStatus.DELIVERY_SUCCESSorder.statusDescription = "Order delivered"if order.insuranceDetails:try:update_insurance_details(order)except:print "Error generating insurance file for order " + str(order.id)session.rollback()returnif order.dataInsuranceDetails:order.dataInsuranceDetails[0].startDate = order.delivery_timestamporder.dataInsuranceDetails[0].expiryDate = order.delivery_timestamp + timedelta(days = 90)if order.source == 2:sod = StoreOrderDetail.get_by(orderId = order.id)sod.payStatus = StorePaymentStatus.FULL_PAY_RECEIVEDif order.pickupStoreId and order.cod:__push_collection_to_hotspot(order, "SALE")for logisticsTxnId, ordersList in logisticsTxnIdOrdersMap.iteritems():enqueue_delivery_success_mail(logisticsTxnId, ordersList)# if order.pickupStoreId:# payment_client = PaymentClient().get_client()# payment_client.createRefund(order.id, order.transaction.id, order.total_amount)# payment_client = PaymentClient().get_client()# payment_client.partiallyCapturePayment(order.transaction.id, order.total_amount, xferBy, xferTxnId, now())# order.cod_reconciliation_timestamp = datetime.datetime.now()# session.commit()try:alert_client = AlertClient().get_client()alert_client.endMonitoringEntity(EntityType.COURIER, "orderId = " + str(order.id))except Exception as e:print "Exception in ending alert in MarkOrderAsDelivered method"print eupdate_trust_level(grouppedOrdersList[0])session.commit()def mark_order_as_received_at_store(orderId, deliveryTimestamp):order = Order.get_by(id=orderId)if order != None or order.status in [OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY, OrderStatus.REACHED_DESTINATION_CITY, OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE, OrderStatus.DELIVERED_AT_STORE]:order.status = OrderStatus.RECEIVED_AT_STOREorder.statusDescription = "Order received at store"order.delivery_timestamp = deliveryTimestampsession.commit()try:alert_client = AlertClient().get_client()alert_client.endMonitoringEntity(EntityType.COURIER, "orderId = " + str(order.id))except Exception as e:print etry:enqueue_received_at_store_email(order)except Exception as e:print edef mark_orders_as_rto(provider_id, returned_orders):for awb, detail in returned_orders.iteritems():orders = Noneorders = Order.query.filter_by(airwaybill_no=awb, logistics_provider_id = provider_id).all()if orders == None or len(orders)==0:continuefor order in orders:if order == None or order.status not in [OrderStatus.SHIPPED_FROM_WH, OrderStatus.DELIVERED_AT_STORE, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY, OrderStatus.REACHED_DESTINATION_CITY, OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE]:continue#raise TransactionServiceException(103, "No order found for the awb:" + awb)order.status = OrderStatus.RTO_IN_TRANSITorder.delivery_timestamp, reason = detail.split('|')order.statusDescription = "Order Returned to Origin:" + reasontry:alert_client = AlertClient().get_client()alert_client.endMonitoringEntity(EntityType.COURIER, "orderId = " + str(order.id))except Exception as e:print "Exception in ending alert in MarkOrderAsRTO method"print eupdate_trust_level(orders[0])session.commit()def get_rto_orders(provider_id):current_time = datetime.datetime.now()to_datetime = datetime.datetime(current_time.year, current_time.month, current_time.day)rto_orders = Order.query.filter_by(logistics_provider_id = provider_id).filter_by(status=OrderStatus.RTO_IN_TRANSIT).filter(Order.delivery_timestamp <= to_datetime).all()return rto_ordersdef get_receive_pending_orders(storeId):return Order.query.filter_by(pickupStoreId = storeId).filter(Order.status.in_((OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY, OrderStatus.REACHED_DESTINATION_CITY, OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE, OrderStatus.DELIVERED_AT_STORE))).all()def get_received_at_store_orders(storeId):return Order.query.filter_by(pickupStoreId = storeId).filter(Order.status.in_((OrderStatus.RECEIVED_AT_STORE, OrderStatus.RET_PICKUP_REQUEST_RAISED))).all()def get_orders_collection_at_store(storeId, fromDate, toDate, onlyCod):query = Order.query.filter(Order.status == OrderStatus.DELIVERY_SUCCESS)if storeId:query = query.filter_by(pickupStoreId = storeId)else:query = query.filter(Order.pickupStoreId != 0)if onlyCod:query = query.filter_by(cod = onlyCod)if fromDate:query = query.filter(Order.delivery_timestamp >= fromDate)if toDate:query = query.filter(Order.delivery_timestamp <= toDate)return query.all()def update_non_delivery_reason(provider_id, undelivered_orders):for awb, reason in undelivered_orders.iteritems():order = Order.query.filter_by(airwaybill_no=awb, logistics_provider_id = provider_id).first()if order == None or order.status == OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE:continue#raise TransactionServiceException(103, "No order found for the awb:" + awb)order.statusDescription = reasonsession.commit()def get_non_delivered_orders_by_courier(provider_id):current_time = datetime.datetime.now()today_datetime = datetime.datetime(current_time.year, current_time.month, current_time.day)upto_datetime = today_datetime - datetime.timedelta(4)orders_not_delivered = Order.query.filter_by(logistics_provider_id = provider_id).filter(Order.status.in_((OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY, OrderStatus.REACHED_DESTINATION_CITY, OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE))).filter(or_(Order.shipping_timestamp <= upto_datetime, Order.pickup_timestamp <= upto_datetime)).all()return orders_not_delivereddef mark_orders_as_local_connected(provider_id, local_connected_orders):for awb, timestamp in local_connected_orders.iteritems():orders = Noneorders = Order.query.filter_by(airwaybill_no=awb, logistics_provider_id = provider_id).all()if orders == None or len(orders)==0:continuefor order in orders:if order == None or order.status not in [OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST]:#raise TransactionServiceException(102, "No order found for the awb: " + awb)continueorder.status = OrderStatus.SHIPPED_TO_DESTINATION_CITYorder.statusDescription = "Left Out of Origin City"current_time = datetime.datetime.now()order.local_connected_timestamp = datetime.datetime(current_time.year, current_time.month, current_time.day)try:monitoredEntity = MonitoredEntity();monitoredEntity.entityType=EntityType.COURIER;monitoredEntity.eventType=OrderStatus.SHIPPED_TO_DESTINATION_CITYmonitoredEntity.entityIdentifier="orderId = " + str(order.id);sec = datetime.datetime.now()#Warn alert time is taken as 14 hrs less than expected delivery timewarn_time1 = (order.expected_delivery_time-timedelta(hours = 14))warn_time2 = sec + timedelta(order.expected_delivery_time - order.expected_shipping_timestamp) - timedelta(sec - order.shipping_time)warn_time = max(warn_time1, warn_time2)#Critical alert time is taken as 13 hrs less than promised delivery timecritical_time1 = (order.expected_delivery_time-timedelta(hours = 10))critical_time2 = sec + timedelta(order.expected_delivery_time - order.expected_shipping_timestamp) - timedelta(sec - order.shipping_time) + timedelta(hours = 5)critical_time = max(critical_time1, critical_time2)monitoredEntity.warnExpiryTime = int(warn_time.strftime("%s"))*1000monitoredEntity.criticalExpiryTime = int(critical_time.strftime("%s"))*1000monitoredEntity.description="providerId = " + str(provider_id) + " destination city " + order.customer_cityalert_client = AlertClient().get_client()alert_client.updateMonitoredObject(monitoredEntity)except Exception as e:print "Exception in updating alert in MarkOrderAsLocalConnected method"print esession.commit()def get_orders_not_local_connected(provider_id):current_time = datetime.datetime.now()to_datetime = datetime.datetime(current_time.year, current_time.month, current_time.day)orders_pending_local_connection = Order.query.filter_by(logistics_provider_id = provider_id).filter(Order.status.in_((OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST))).filter(or_(Order.shipping_timestamp <= to_datetime, Order.pickup_timestamp <= to_datetime)).all()return orders_pending_local_connectiondef mark_orders_as_destinationCityReached(provider_id, destination_city_reached_orders):for awb, timestamp in destination_city_reached_orders.iteritems():orders = Noneorders = Order.query.filter_by(airwaybill_no=awb, logistics_provider_id = provider_id).all()if orders == None or len(orders)==0:continuefor order in orders:if order == None or order.status not in [OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY]:continue#raise TransactionServiceException(103, "No order found for the awb:" + awb)order.status = OrderStatus.REACHED_DESTINATION_CITYorder.statusDescription = "Reached Destination City"order.reached_destination_timestamp = timestamptry:monitoredEntity = MonitoredEntity();monitoredEntity.entityType=EntityType.COURIER;monitoredEntity.eventType=OrderStatus.REACHED_DESTINATION_CITYmonitoredEntity.entityIdentifier="orderId = " + str(order.id);sec = datetime.datetime.now()#Warn alert time is taken as expected delivery timewarn_time1 = (order.expected_delivery_time)warn_time2 = sec + timedelta(order.expected_delivery_time - order.expected_shipping_time) - timedelta(sec - order.shipping_time)warn_time = max(warn_time1, warn_time2)#Critical alert time is taken as 13 hrs less than promised delivery timecritical_time1 = (order.expected_delivery_time + timedelta(hours = 5))critical_time2 = sec + timedelta(order.expected_delivery_time - order.expected_shipping_time) - timedelta(sec - order.shipping_time) + timedelta(hours = 5)critical_time = max(critical_time1, critical_time2)monitoredEntity.warnExpiryTime = int(warn_time.strftime("%s"))*1000monitoredEntity.criticalExpiryTime = int(critical_time.strftime("%s"))*1000monitoredEntity.description="providerId = " + str(provider_id) + " destination city " + order.customer_cityalert_client = AlertClient().get_client()alert_client.updateMonitoredObject(monitoredEntity)except Exception as e:print "Exception in updating alert in MarkOrderAsDestCityReached method"print esession.commit()def mark_orders_as_firstDeliveryAttempted(provider_id, first_atdl_orders):for awb, detail in first_atdl_orders.iteritems():orders = Noneorders = Order.query.filter_by(airwaybill_no=awb, logistics_provider_id = provider_id).all()if orders == None or len(orders)==0:continuefor order in orders:if order == None or order.status not in [OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY, OrderStatus.REACHED_DESTINATION_CITY]:continue#raise TransactionServiceException(103, "No order found for the awb:" + awb)order.status = OrderStatus.FIRST_DELIVERY_ATTEMPT_MADEorder.first_dlvyatmp_timestamp, reason = detail.split('|')order.statusDescription = reasontry:monitoredEntity = MonitoredEntity();monitoredEntity.entityType=EntityType.COURIER;monitoredEntity.eventType=OrderStatus.FIRST_DELIVERY_ATTEMPT_MADEmonitoredEntity.entityIdentifier="orderId = " + str(order.id);adjustedDeliveryDaysfor1day = adjust_delivery_time(datetime.datetime.now(), 1);adjustedDeliveryDaysfor2days = adjust_delivery_time(datetime.datetime.now(), 2);sec = datetime.datetime.now()#Warn alert time is taken as 16 hrswarn_time = (sec + timedelta(days=(adjustedDeliveryDaysfor1day-1)) + timedelta(hours=24))#Critical alert time is taken as 26 hrscritical_time = (sec + timedelta(days=(adjustedDeliveryDaysfor2days-2)) + timedelta(hours=48))monitoredEntity.warnExpiryTime = int(warn_time.strftime("%s"))*1000monitoredEntity.criticalExpiryTime = int(critical_time.strftime("%s"))*1000monitoredEntity.description="providerId = " + str(provider_id) + " first attempt timestamp" + order.first_dlvyatmp_timestampalert_client = AlertClient().get_client()alert_client.updateMonitoredObject(monitoredEntity)except Exception as e:print "Exception in updating alert in MarkOrdersAsFirstDeliveryAttempted method"print esession.commit()def get_orders_not_met_expected_delivery_date():current_time = datetime.datetime.now()today_datetime = datetime.datetime(current_time.year, current_time.month, current_time.day)orders_not_delivered = Order.query.filter(Order.status.in_((OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY, OrderStatus.REACHED_DESTINATION_CITY))).filter(Order.expected_delivery_time <= today_datetime).all()return orders_not_delivereddef get_alerts(type, warehouseId, status, timestamp):query = Alert.query.filter(Alert.warehouseId == warehouseId)if type != -1 :query = query.filter(Alert.type == type)if status != -1 :query = query.filter(Alert.status == status)if timestamp:query = query.filter(Alert.timestamp >= to_py_date(timestamp))query = query.order_by(desc(Alert.timestamp))return query.all()def add_alert(type, warehouseId, description):alert = Alert()alert.type = typealert.status = 1alert.description = descriptionalert.timestamp = datetime.datetime.now()alert.warehouseId = warehouseIdsession.commit()def mark_alerts_as_seen(warehouseId):query = Alert.query.filter(Alert.warehouseId == warehouseId).filter(Alert.status == 1)alerts = query.all()for alert in alerts:alert.status = 0session.commit()def get_valid_order_count():'''Returns the number of orders which we processed. The reshipped orders are notcounted since there'll always be a new compensating order present.'''return Order.query.filter(Order.status >= OrderStatus.SUBMITTED_FOR_PROCESSING).filter(not_(Order.status.in_((OrderStatus.RTO_RESHIPPED, OrderStatus.DOA_INVALID_RESHIPPED, OrderStatus.DOA_VALID_RESHIPPED, OrderStatus.COD_VERIFICATION_FAILED)))).count()def get_cust_count_with_successful_txn():'''Returns the number of distinct customers who have done successful transactions.It uses the sqlalchemy func module to construct an efficient query.'''return session.query(func.count(distinct(Order.customer_id))).filter(Order.status >= OrderStatus.SUBMITTED_FOR_PROCESSING).scalar()def get_valid_orders_amount_range():'''Returns a list containing the minimum and maximum amount across allorders placed with us. No need to consider reshippped orders for min/maxamount of orders.'''return session.query(func.min(Order.total_amount), func.max(Order.total_amount)).filter(Order.status >= OrderStatus.SUBMITTED_FOR_PROCESSING).one()def get_valid_orders(limit, onlyStore):'''Returns the last limit number of valid orders placed with us. Ignored thelimit if it's passed as 0. Raises an excpetion if the supplied limit isless than 0.'''if limit < 0:raise TransactionServiceException(101, "Invalid argument limit " + limit)query = Order.query.filter(Order.status >= OrderStatus.COD_VERIFICATION_PENDING)if onlyStore:query = query.filter(Order.pickupStoreId != 0)query = query.order_by(desc(Order.created_timestamp))if limit != 0:query = query.limit(limit)return query.all()def get_next_invoice_number(orderType):if OrderType.B2Cbulk == orderType:orderType = OrderType.B2Centity_id = InvoiceIDGenerator.query.filter(InvoiceIDGenerator.orderType == orderType).with_lockmode("update").one()invoice_number = entity_id.id + 1entity_id.id = invoice_numberreturn invoice_numberdef get_next_invoice_counter(seller_id, warehouse_id, hsnCode):#Sequence would now be maintained through single order for seller#entity_id = InvoiceCounterGenerator.query.filter(InvoiceCounterGenerator.orderType == orderType).filter(InvoiceCounterGenerator.stateId == stateId).filter(InvoiceCounterGenerator.companyId==companyId).with_lockmode("update").one()entity_id = SellerWarehouse.query.filter(SellerWarehouse.warehouse_id == warehouse_id).filter(SellerWarehouse.seller_id==seller_id).with_lockmode("update").one()prefix = entity_id.prefixif hsnCode=="NOGST":document_number = entity_id.challan_id + 1entity_id.challan_id = document_numberprefix = 'CHLN-' + prefixelse:document_number = entity_id.id + 1entity_id.id = document_numberret_invoiceNo = prefix + str(document_number)return ret_invoiceNodef toggle_doa_flag(order_id):order = get_order(order_id)if(order.doaFlag):order.doaFlag = Falseelse:order.doaFlag = Truesession.commit()return order.doaFlagdef mark_order_doa_request_received(orderId):order = get_order(orderId)if order.status != OrderStatus.DELIVERY_SUCCESS:return Falseorder.status = OrderStatus.DOA_REQUEST_RECEIVEDorder.statusDescription = "DOA Request Received"session.commit()return Truedef mark_order_doa_request_authorized(orderId, isAuthorized, fromStore, isReship):order = get_order(orderId)if order.status != OrderStatus.DOA_REQUEST_RECEIVED:return Falseif isAuthorized:order.status = OrderStatus.DOA_REQUEST_AUTHORIZEDorder.statusDescription = "DOA Request Authorized"if order.source == 2:if fromStore:if isReship:new_order = __clone_order(order, False, False)order.reship_timestamp = datetime.datetime.now()order.new_order_id = new_order.idelse:sod = StoreOrderDetail.get_by(orderId = order.id)if sod.cashAmount > 0:__push_store_collection_to_hotspot(order, "RefundFromStore", -sod.cashAmount, 0)if sod.cardAmount == 0:sod.payStatus = StorePaymentStatus.ADV_REFUNDEDelse:sod.payStatus = StorePaymentStatus.REFUND_REQUESTEDorder.refund_timestamp = datetime.datetime.now()order.refunded_by = "CRM Outbound Team"sod.cashRefundAmount = sod.cashAmountsod.cardRefundAmount = sod.cardAmountelse:order.status = OrderStatus.DELIVERY_SUCCESSorder.statusDescription = "Order delivered"session.commit()return Truedef mark_order_return_request_received(orderId):order = get_order(orderId)if order.status != OrderStatus.DELIVERY_SUCCESS:return Falseorder.status = OrderStatus.RET_REQUEST_RECEIVEDorder.statusDescription = "Return Request Received"session.commit()return Truedef mark_order_return_request_authorized(orderId, isAuthorized, fromStore, isReship):order = get_order(orderId)if order.status != OrderStatus.RET_REQUEST_RECEIVED:return Falseif isAuthorized:order.status = OrderStatus.RET_REQUEST_AUTHORIZEDorder.statusDescription = "Return Request Authorized"if order.source == 2:if fromStore:if isReship:new_order = __clone_order(order, False, False)order.reship_timestamp = datetime.datetime.now()order.new_order_id = new_order.idelse:sod = StoreOrderDetail.get_by(orderId = order.id)if sod.cashAmount > 0:__push_store_collection_to_hotspot(order, "RefundFromStore", -sod.cashAmount, 0)if sod.cardAmount == 0:sod.payStatus = StorePaymentStatus.ADV_REFUNDEDelse:sod.payStatus = StorePaymentStatus.REFUND_REQUESTEDorder.refund_timestamp = datetime.datetime.now()order.refunded_by = "CRM Outbound Team"sod.cashRefundAmount = sod.cashAmountsod.cardRefundAmount = sod.cardAmountelse:order.status = OrderStatus.DELIVERY_SUCCESSorder.statusDescription = "Order delivered"session.commit()return Truedef request_pickup_number(order_id, providerId):order = get_order(order_id)if order.status != OrderStatus.DELIVERY_SUCCESS and order.status != OrderStatus.DOA_REQUEST_AUTHORIZED and order.status != OrderStatus.RET_REQUEST_AUTHORIZED:return Falseif order.status == OrderStatus.RET_REQUEST_AUTHORIZED:order.status = OrderStatus.RET_PICKUP_REQUEST_RAISEDorder.statusDescription = "Pick up requested for RETURN"else:order.status = OrderStatus.DOA_PICKUP_REQUEST_RAISEDorder.statusDescription = "Pick up requested for DOA"order.doa_logistics_provider_id = providerIdsession.commit()return Truedef authorize_pickup(order_id, pickup_number, providerId):order = get_order(order_id)if order.status not in [OrderStatus.DOA_PICKUP_REQUEST_RAISED, OrderStatus.RET_PICKUP_REQUEST_RAISED]:return Falseif order.doa_logistics_provider_id is not None:providerId = order.doa_logistics_provider_id #previously we are not storing this so data is taken from omdashboardusersubject = 'Pickup details'filename = "/tmp/" + str(order.id) +".pdf"try:inventory_client = InventoryClient().get_client()warehouse = inventory_client.getWarehouse(order.warehouse_id)logistics_client = LogisticsClient().get_client()provider = logistics_client.getProvider(providerId)provider_name = provider.nameto_addr = order.customer_emailtoday = date.today().strftime("%d-%B-%Y (%A)")raw_message = '''Dear %(customer_name)s,Would like to inform you that we have instructed %(provider_name)s to pick up the material from the below mentioned address on %(date)s. %(provider_name)s pickup request number is %(pickup_request_no)s.'Take a printout of the attachment in this mail which contains the delivery address and paste it on the packed parcel. Kindly keep the parcel ready.Pickup will happen from the below mentioned address:-%(customer_address)sDo let us know in case of any concernsThanks & Regards%(source_name)s Team'''message = dedent(raw_message) % {'customer_name' : order.customer_name,'order_id' : order_id,'provider_name' : provider_name,'date': today,'pickup_request_no' : pickup_number,'customer_address' : __get_order_address(order),'source_name' : source_name}print message__generate_return_advice(order, warehouse, provider, filename)if order.source in [OrderSource.WEBSITE, OrderSource.AMAZON, OrderSource.JUNGLEE]:mail(help_user, help_password, [to_addr], subject, message, [get_attachment_part(filename)])order.pickupRequestNo = pickup_numberif order.status == OrderStatus.RET_PICKUP_REQUEST_RAISED:order.status = OrderStatus.RET_PICKUP_CONFIRMEDorder.statusDescription = "RETURN pick up confirmed"else:order.status = OrderStatus.DOA_PICKUP_CONFIRMEDorder.statusDescription = "DOA pick up confirmed"order.doa_auth_timestamp = datetime.datetime.now()session.commit()return Trueexcept Exception as e:print sys.exc_info()traceback.print_tb(sys.exc_info()[2])return Falsefinally:if os.path.exists(filename):os.remove(filename)def mark_doas_as_picked_up(provider_id, pickup_details):for pickupNo, doa_pickup_timestamp in pickup_details.iteritems():order = Order.query.filter_by(pickupRequestNo=pickupNo, doa_logistics_provider_id = provider_id).first()if order == None or order.status != OrderStatus.DOA_PICKUP_CONFIRMED:#raise TransactionServiceException(102, "No order found for the awb: " + awb)continueorder.status = OrderStatus.DOA_RETURN_IN_TRANSITorder.statusDescription = "DOA picked up by Courier Company"order.doa_pickup_timestamp = doa_pickup_timestampsession.commit()def get_doas_not_picked_up(provider_id):current_time = datetime.datetime.now()to_datetime = datetime.datetime(current_time.year, current_time.month, current_time.day)orders_not_picked_up = Order.query.filter_by(doa_logistics_provider_id = provider_id).filter_by(status=OrderStatus.DOA_PICKUP_CONFIRMED).filter(Order.doa_auth_timestamp <= to_datetime).all()return orders_not_picked_updef mark_return_orders_as_picked_up(provider_id, pickup_details):for pickupNo, return_order_pickup_timestamp in pickup_details.iteritems():order = Order.query.filter_by(pickupRequestNo=pickupNo, doa_logistics_provider_id = provider_id).first()if order == None or order.status != OrderStatus.RET_PICKUP_CONFIRMED:#raise TransactionServiceException(102, "No order found for the awb: " + awb)continueorder.status = OrderStatus.RET_RETURN_IN_TRANSITorder.statusDescription = "Return order picked up by Courier Company"order.doa_pickup_timestamp = return_order_pickup_timestampsession.commit()def get_return_orders_not_picked_up(provider_id):current_time = datetime.datetime.now()to_datetime = datetime.datetime(current_time.year, current_time.month, current_time.day)orders_not_picked_up = Order.query.filter_by(doa_logistics_provider_id = provider_id).filter_by(status=OrderStatus.RET_PICKUP_CONFIRMED).filter(Order.doa_auth_timestamp <= to_datetime).all()return orders_not_picked_updef receive_return(order_id, receiveCondition, receiveFreebie, serialNumbers):order = get_order(order_id)scanFreebie = FalsegrouppedOrdersList = []if order.logisticsTransactionId:grouppedOrdersList = get_group_orders_by_logistics_txn_id(order.logisticsTransactionId)else:grouppedOrdersList.append(order)orderCurrentStatus = order.statusif order.status in [OrderStatus.DOA_PICKUP_CONFIRMED, OrderStatus.DOA_RETURN_IN_TRANSIT]:if receiveCondition == 0:order.status = OrderStatus.DOA_RECEIVED_PRESTINEorder.statusDescription = "DOA package received"scanFreebie = receiveFreebieelif receiveCondition == 1:order.status = OrderStatus.DOA_RECEIVED_DAMAGEDorder.statusDescription = "DOA received damaged"elif receiveCondition == 2:order.status = OrderStatus.DOA_LOST_IN_TRANSITorder.statusDescription = "DOA lost in transit"order.received_return_timestamp = datetime.datetime.now()elif order.status in [OrderStatus.RET_PICKUP_CONFIRMED, OrderStatus.RET_RETURN_IN_TRANSIT]:if receiveCondition == 0:order.status = OrderStatus.RET_RECEIVED_PRESTINEorder.statusDescription = "RETURN package received"scanFreebie = receiveFreebieelif receiveCondition == 1:order.status = OrderStatus.RET_RECEIVED_DAMAGEDorder.statusDescription = "RETURN received damaged"elif receiveCondition == 2:order.status = OrderStatus.RET_LOST_IN_TRANSITorder.statusDescription = "RETURN lost in transit"order.received_return_timestamp = datetime.datetime.now()elif order.status == OrderStatus.RTO_IN_TRANSIT :for orderObj in grouppedOrdersList:if receiveCondition == 0:orderObj.status = OrderStatus.RTO_RECEIVED_PRESTINEorderObj.statusDescription = "Returned to origin"if orderObj.freebieItemId:scanFreebie = Trueelif receiveCondition == 1:orderObj.status = OrderStatus.RTO_RECEIVED_DAMAGEDorderObj.statusDescription = "RTO received damaged"elif receiveCondition == 2:orderObj.status = OrderStatus.RTO_LOST_IN_TRANSITorderObj.statusDescription = "RTO lost in transit"orderObj.received_return_timestamp = datetime.datetime.now()else:return False# For OUR warehouses, we need to scan in items for every returninventoryClient = InventoryClient().get_client()warehouse = inventoryClient.getWarehouse(order.warehouse_id)if warehouse.billingType == BillingType.OURS or warehouse.billingType == BillingType.OURS_EXTERNAL:scanMap = {OrderStatus.RTO_RECEIVED_PRESTINE : ScanType.SALE_RET,OrderStatus.RTO_RECEIVED_DAMAGED : ScanType.SALE_RET_UNUSABLE,OrderStatus.RTO_LOST_IN_TRANSIT : ScanType.LOST_IN_TRANSIT,OrderStatus.DOA_RECEIVED_PRESTINE : ScanType.DOA_IN,OrderStatus.DOA_RECEIVED_DAMAGED : ScanType.DOA_IN,OrderStatus.DOA_LOST_IN_TRANSIT : ScanType.LOST_IN_TRANSIT}if orderCurrentStatus == OrderStatus.RTO_IN_TRANSIT:order = grouppedOrdersList[0]if order.transaction.payment_option == capitalFloatPayMethod:total_amount = 0for ordObj in grouppedOrdersList:total_amount = total_amount + ordObj.total_amount + ordObj.shippingCost - ordObj.gvAmountcreditObj = __creditHistoryObj(order.customer_id, 1, order.transaction.id, total_amount, CreditTxnType.BLOCKED_REVERSED, order.logisticsTransactionId)creditTxns = []creditTxns.append(creditObj)try:process_credit_transaction(order.transaction.id, order.customer_id, 1, creditTxns)except:traceback.print_exc()session.rollback()return Falsefor orderObj in grouppedOrdersList:if scanMap.has_key(orderObj.status):scanType = scanMap[orderObj.status]lineitem = orderObj.lineitems[0]catalogClient = CatalogClient().get_client()item = catalogClient.getItem(lineitem.item_id)warehouseClient = WarehouseClient().get_client()if warehouse.billingType == BillingType.OURS or scanType != ScanType.SALE_RET:if item.type == ItemType.SERIALIZED:if lineitem.quantity > 1:serialNoList = lineitem.serial_number.split(',')for serialNumber in serialNoList:warehouseClient.scanSerializedItemForOrder(serialNumber, scanType, orderObj.id, orderObj.fulfilmentWarehouseId, 1, orderObj.warehouse_id)else:warehouseClient.scanSerializedItemForOrder(lineitem.serial_number, scanType, orderObj.id, orderObj.fulfilmentWarehouseId, lineitem.quantity, orderObj.warehouse_id)else:warehouseClient.scanForOrder(None, scanType, lineitem.quantity, orderObj.id, orderObj.fulfilmentWarehouseId, orderObj.warehouse_id)if warehouse.billingType == BillingType.OURS_EXTERNAL and scanType == ScanType.SALE_RET:warehouseClient.scanForOursExternalSaleReturn(orderObj.id, lineitem.transfer_price)if scanFreebie:warehouseClient.scanfreebie(orderObj.id, orderObj.freebieItemId, 0, scanType)else:if scanMap.has_key(order.status):scanType = scanMap[order.status]lineitem = order.lineitems[0]catalogClient = CatalogClient().get_client()item = catalogClient.getItem(lineitem.item_id)warehouseClient = WarehouseClient().get_client()if warehouse.billingType == BillingType.OURS or scanType != ScanType.SALE_RET:if item.type == ItemType.SERIALIZED:if lineitem.quantity > 1:if serialNumbers is None or len(serialNumbers)==0:return Falseelse:serialNoList = serialNumbers.split(',')for serialNumber in serialNoList:warehouseClient.scanSerializedItemForOrder(serialNumber, scanType, order.id, order.fulfilmentWarehouseId, 1, order.warehouse_id)else:warehouseClient.scanSerializedItemForOrder(lineitem.serial_number, scanType, order.id, order.fulfilmentWarehouseId, lineitem.quantity, order.warehouse_id)else:warehouseClient.scanForOrder(None, scanType, lineitem.quantity, order.id, order.fulfilmentWarehouseId, order.warehouse_id)if warehouse.billingType == BillingType.OURS_EXTERNAL and scanType == ScanType.SALE_RET:warehouseClient.scanForOursExternalSaleReturn(order.id, lineitem.transfer_price)if scanFreebie:warehouseClient.scanfreebie(order.id, order.freebieItemId, 0, scanType)session.commit()return Truedef validate_doa(order_id, is_valid):order = get_order(order_id)if order.status != OrderStatus.DOA_RECEIVED_PRESTINE:return Falseif is_valid:order.status = OrderStatus.DOA_CERT_VALIDorder.statusDescription = "DOA Certificate Valid"else:order.status = OrderStatus.DOA_CERT_INVALIDorder.statusDescription = "DOA Certificate Invalid"update_trust_level(order)session.commit()return Truedef validate_return_product(order_id, is_usable):order = get_order(order_id)if order.status != OrderStatus.RET_RECEIVED_PRESTINE:return FalsescanType = ScanType.SALE_RET_UNUSABLEif is_usable:order.status = OrderStatus.RET_PRODUCT_USABLEorder.statusDescription = "Return product usable"scanType = ScanType.SALE_RETelse:order.status = OrderStatus.RET_PRODUCT_UNUSABLEorder.statusDescription = "Return product unusable"update_trust_level(order)session.commit()# For OUR warehouses, we need to scan in items for every returninventoryClient = InventoryClient().get_client()warehouse = inventoryClient.getWarehouse(order.warehouse_id)if warehouse.billingType == BillingType.OURS or warehouse.billingType == BillingType.OURS_EXTERNAL:lineitem = order.lineitems[0]catalogClient = CatalogClient().get_client()item = catalogClient.getItem(lineitem.item_id)warehouse_client = WarehouseClient().get_client()if warehouse.billingType == BillingType.OURS or scanType != ScanType.SALE_RET:if item.type == ItemType.SERIALIZED:warehouse_client.scanSerializedItemForOrder(lineitem.serial_number, scanType, order.id, order.fulfilmentWarehouseId, lineitem.quantity, order.warehouse_id)else:warehouse_client.scanForOrder(None, scanType, lineitem.quantity, order.id, order.fulfilmentWarehouseId, order.warehouse_id)if scanType == ScanType.SALE_RET and warehouse.billingType == BillingType.OURS_EXTERNAL:warehouse_client.scanForOursExternalSaleReturn(order.id, lineitem.transfer_price)return Truedef reship_order(order_id):"""If the order is in RTO_RECEIVED_PRESTINE or DOA_CERT_INVALID state, it does the following:1. Creates a new order for processing in the BILLED state. All billing information is saved.2. Marks the current order as one of the final states RTO_RESHIPPED and DOA_INVALID_RESHIPPED depending on what state the order started in.If the order is in DOA_CERT_VALID state, it does the following:1. Creates a new order for processing in the SUBMITTED_FOR_PROCESSING state.2. Creates a return order for the warehouse executive to return the DOA material.3. Marks the current order as the final DOA_VALID_RESHIPPED state.Returns the id of the newly created order.Throws an exception if the order with the given id couldn't be found.Parameters:- orderId"""order = get_order(order_id)alreadyReshipped = False#If this order was from store and it was already marked refunded then this order#should not be reshipped.if order.source == 2:sod = StoreOrderDetail.get_by(orderId = order.id)if sod.payStatus in (StorePaymentStatus.ADV_REFUNDED , StorePaymentStatus.REFUND_INITIATED, \StorePaymentStatus.REFUND_REQUESTED, StorePaymentStatus.REFUNDED):raise TransactionServiceException(112, "This order should be refunded")#If this order was from store and a new order Id has already been set then it means that#a new order corresponding to this order has already been shipped.if order.source == 2 and order.new_order_id:alreadyReshipped = Trueif order.status == OrderStatus.RTO_RECEIVED_PRESTINE:order.status = OrderStatus.RTO_RESHIPPEDorder.statusDescription = "Order Reshipped"if not alreadyReshipped:new_order = __clone_order(order, True, order.cod)update_trust_level(order)__scan_for_reship_order(order_id, new_order)elif order.status == OrderStatus.RTO_RECEIVED_DAMAGED:order.status = OrderStatus.RTO_DAMAGED_RESHIPPEDorder.statusDescription = "Order Reshipped Received Damaged"if not alreadyReshipped:new_order = __clone_order(order, False, order.cod)ret_order = __create_return_order(order)elif order.status == OrderStatus.RTO_LOST_IN_TRANSIT:order.status = OrderStatus.RTO_LOST_IN_TRANSIT_RESHIPPEDorder.statusDescription = "Order Reshipped Lost In Transit"if not alreadyReshipped:new_order = __clone_order(order, False, order.cod)elif order.status == OrderStatus.LOST_IN_TRANSIT:order.status = OrderStatus.LOST_IN_TRANSIT_RESHIPPEDorder.statusDescription = "Order Reshipped Lost In Transit"if not alreadyReshipped:new_order = __clone_order(order, False, order.cod)elif order.status == OrderStatus.DOA_CERT_INVALID:order.status = OrderStatus.DOA_INVALID_RESHIPPEDorder.statusDescription = "Order Reshipped"if not alreadyReshipped:new_order = __clone_order(order, True, False)__scan_for_reship_order(order_id, new_order)elif order.status == OrderStatus.DOA_CERT_VALID:order.status = OrderStatus.DOA_VALID_RESHIPPEDorder.statusDescription = "Order Reshipped"if not alreadyReshipped:new_order = __clone_order(order, False, False)ret_order = __create_return_order(order)elif order.status == OrderStatus.DOA_RECEIVED_DAMAGED:order.status = OrderStatus.DOA_RESHIPPED_RCVD_DAMAGEDorder.statusDescription = "Order Reshipped Received Damaged"if not alreadyReshipped:new_order = __clone_order(order, False, False)ret_order = __create_return_order(order)elif order.status == OrderStatus.DOA_LOST_IN_TRANSIT:order.status = OrderStatus.DOA_RESHIPPED_LOST_IN_TRANSITorder.statusDescription = "Order Reshipped Lost In Transit"if not alreadyReshipped:new_order = __clone_order(order, False, False)elif order.status == OrderStatus.RET_PRODUCT_USABLE:order.status = OrderStatus.RET_PRODUCT_USABLE_RESHIPPEDorder.statusDescription = "Order Reshipped"if not alreadyReshipped:new_order = __clone_order(order, False, False)elif order.status == OrderStatus.RET_PRODUCT_UNUSABLE:order.status = OrderStatus.RET_PRODUCT_UNUSABLE_RESHIPPEDorder.statusDescription = "Order Reshipped"if not alreadyReshipped:new_order = __clone_order(order, False, False)ret_order = __create_return_order(order)elif order.status == OrderStatus.RET_RECEIVED_DAMAGED:order.status = OrderStatus.RET_RESHIPPED_RCVD_DAMAGEDorder.statusDescription = "Order Reshipped Received Damaged"if not alreadyReshipped:new_order = __clone_order(order, False, False)ret_order = __create_return_order(order)elif order.status == OrderStatus.RET_LOST_IN_TRANSIT:order.status = OrderStatus.RET_RESHIPPED_LOST_IN_TRANSITorder.statusDescription = "Order Reshipped Lost In Transit"if not alreadyReshipped:new_order = __clone_order(order, False, False)else:raise TransactionServiceException(112, "This order can't be reshipped")if not alreadyReshipped:order.reship_timestamp = datetime.datetime.now()order.new_order_id = new_order.idsession.commit()return new_order.idelse:session.commit()return order.new_order_iddef __scan_for_reship_order(order_id, new_order):inventoryClient = InventoryClient().get_client()warehouse = inventoryClient.getWarehouse(new_order.warehouse_id)if warehouse.billingType == BillingType.OURS:warehouseClient = WarehouseClient().get_client()inventoryItem = warehouseClient.getInventoryItemFromOrder(order_id)warehouseClient.scanForOrder(inventoryItem, ScanType.SALE, new_order.lineitems[0].quantity, new_order.id, new_order.fulfilmentWarehouseId, new_order.warehouse_id)if new_order.freebieItemId:warehouseClient = WarehouseClient().get_client()inventoryItem = warehouseClient.reshipfreebie(order_id, new_order.id, new_order.freebieItemId, ScanType.SALE)def refund_order(order_id, refunded_by, reason):"""If the order is in RTO_RECEIVED_PRESTINE, DOA_CERT_VALID or DOA_CERT_INVALID state, it does the following:1. Creates a refund request for batch processing.2. Creates a return order for the warehouse executive to return the shipped material.3. Marks the current order as RTO_REFUNDED, DOA_VALID_REFUNDED or DOA_INVALID_REFUNDED final states.If the order is in SUBMITTED_FOR_PROCESSING or INVENTORY_LOW state, it does the following:1. Creates a refund request for batch processing.2. Cancels the reservation of the item in the warehouse.3. Marks the current order as the REFUNDED final state.For all COD orders, if the order is in INIT, SUBMITTED_FOR_PROCESSING or INVENTORY_LOW state, it does the following:1. Cancels the reservation of the item in the warehouse.2. Marks the current order as CANCELED.In all cases, it updates the reason for cancellation or refund and the person who performed the action.Returns True if it is successful, False otherwise.Throws an exception if the order with the given id couldn't be found.Parameters:- order_id- refunded_by- reason"""logging.info("Refunding order id: " + str(order_id))order = get_order(order_id)if order.cod:logging.info("Refunding COD order with status " + str(order.status))status_transition = refund_status_transitionif order.status not in status_transition.keys():raise TransactionServiceException(114, "This order can't be refunded")if order.status in [OrderStatus.COD_VERIFICATION_PENDING, OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.LOW_INV_PO_RAISED, OrderStatus.LOW_INV_REVERSAL_IN_PROCESS, OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT, OrderStatus.ACCEPTED]:__update_inventory_reservation(order, refund=True)order.statusDescription = "Order Cancelled"#Shipment Id and Airway Bill No should be none in case of Cancellationorder.logisticsTransactionId = Noneorder.tracking_id = Noneorder.airwaybill_no = Noneelif order.status == OrderStatus.BILLED:__create_return_order(order)order.statusDescription = "Order Cancelled"elif order.status in [OrderStatus.RTO_RECEIVED_PRESTINE, OrderStatus.RTO_RECEIVED_DAMAGED, OrderStatus.RTO_LOST_IN_TRANSIT]:if order.status != OrderStatus.RTO_LOST_IN_TRANSIT:__create_return_order(order)order.statusDescription = "RTO Refunded"elif order.status in [OrderStatus.LOST_IN_TRANSIT]:#__create_return_order(order)order.statusDescription = "Lost in Transit Refunded"elif order.status in [OrderStatus.DOA_CERT_INVALID, OrderStatus.DOA_CERT_VALID, OrderStatus.DOA_RECEIVED_DAMAGED, OrderStatus.DOA_LOST_IN_TRANSIT] :if order.status != OrderStatus.DOA_LOST_IN_TRANSIT:__create_return_order(order)__create_refund(order, 0, 'Should be unreachable for now')order.statusDescription = "DOA Refunded"elif order.status in [OrderStatus.RET_PRODUCT_UNUSABLE, OrderStatus.RET_PRODUCT_USABLE, OrderStatus.RET_RECEIVED_DAMAGED, OrderStatus.RET_LOST_IN_TRANSIT] :if order.status != OrderStatus.RET_LOST_IN_TRANSIT:__create_return_order(order)__create_refund(order, 0, 'Should be unreachable for now')order.statusDescription = "Return Refunded"elif order.status == OrderStatus.CANCEL_REQUEST_CONFIRMED:if order.previousStatus in [OrderStatus.COD_VERIFICATION_PENDING, OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.LOW_INV_PO_RAISED, OrderStatus.LOW_INV_REVERSAL_IN_PROCESS, OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT, OrderStatus.ACCEPTED]:__update_inventory_reservation(order, refund=True)order.statusDescription = "Order Cancelled on customer request"elif order.previousStatus == OrderStatus.BILLED:__create_return_order(order)order.statusDescription = "Order Cancelled on customer request"order.received_return_timestamp = datetime.datetime.now()else:status_transition = {OrderStatus.LOST_IN_TRANSIT : OrderStatus.LOST_IN_TRANSIT_REFUNDED,OrderStatus.RTO_RECEIVED_PRESTINE : OrderStatus.RTO_REFUNDED,OrderStatus.RTO_RECEIVED_DAMAGED : OrderStatus.RTO_DAMAGED_REFUNDED,OrderStatus.RTO_LOST_IN_TRANSIT : OrderStatus.RTO_LOST_IN_TRANSIT_REFUNDED,OrderStatus.DOA_CERT_INVALID : OrderStatus.DOA_INVALID_REFUNDED,OrderStatus.DOA_CERT_VALID : OrderStatus.DOA_VALID_REFUNDED,OrderStatus.DOA_RECEIVED_DAMAGED : OrderStatus.DOA_REFUNDED_RCVD_DAMAGED,OrderStatus.DOA_LOST_IN_TRANSIT : OrderStatus.DOA_REFUNDED_LOST_IN_TRANSIT,OrderStatus.RET_PRODUCT_UNUSABLE : OrderStatus.RET_PRODUCT_UNUSABLE_REFUNDED,OrderStatus.RET_PRODUCT_USABLE : OrderStatus.RET_PRODUCT_USABLE_REFUNDED,OrderStatus.RET_RECEIVED_DAMAGED : OrderStatus.RET_REFUNDED_RCVD_DAMAGED,OrderStatus.RET_LOST_IN_TRANSIT : OrderStatus.RET_REFUNDED_LOST_IN_TRANSIT,OrderStatus.SUBMITTED_FOR_PROCESSING : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,OrderStatus.INVENTORY_LOW : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,OrderStatus.LOW_INV_PO_RAISED : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,OrderStatus.LOW_INV_REVERSAL_IN_PROCESS : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,OrderStatus.ACCEPTED : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,OrderStatus.BILLED : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,OrderStatus.CANCEL_REQUEST_CONFIRMED : OrderStatus.CANCELLED_ON_CUSTOMER_REQUEST,OrderStatus.PAYMENT_FLAGGED : OrderStatus.PAYMENT_FLAGGED_DENIED}if order.status not in status_transition.keys():raise TransactionServiceException(114, "This order can't be refunded")if order.status in [OrderStatus.RTO_RECEIVED_PRESTINE, OrderStatus.RTO_RECEIVED_DAMAGED, OrderStatus.RTO_LOST_IN_TRANSIT] :if order.status != OrderStatus.RTO_LOST_IN_TRANSIT:__create_return_order(order)__create_refund(order, order.wallet_amount, 'Order #{0} is RTO refunded'.format(order.id))order.statusDescription = "RTO Refunded"#Start:- Added By Manish Sharma for Creating a new Ticket: Category- RTO Refund on 21-Jun-2013try:crmServiceClient = CRMClient().get_client()ticket =Ticket()activity = Activity()description = "Creating Ticket for " + order.statusDescription + " Order"ticket.creatorId = 1ticket.assigneeId = 34ticket.category = TicketCategory.RTO_REFUNDticket.priority = TicketPriority.MEDIUMticket.status = TicketStatus.OPENticket.description = descriptionticket.orderId = order.idactivity.creatorId = 1activity.ticketAssigneeId = ticket.assigneeIdactivity.type = ActivityType.OTHERactivity.description = descriptionactivity.ticketCategory = ticket.categoryactivity.ticketDescription = ticket.descriptionactivity.ticketPriority = ticket.priorityactivity.ticketStatus = ticket.statusticket.customerId= order.customer_idticket.customerEmailId = order.customer_emailticket.customerMobileNumber = order.customer_mobilenumberticket.customerName = order.customer_nameactivity.customerId = ticket.customerIdactivity.customerEmailId = order.customer_emailactivity.customerMobileNumber = order.customer_mobilenumberactivity.customerName = order.customer_namecrmServiceClient.insertTicket(ticket, activity)except:print "Ticket for RTO Refund is not created."#End:- Added By Manish Sharma for Creating a new Ticket: Category- RTO Refund on 21-Jun-2013elif order.status in [OrderStatus.LOST_IN_TRANSIT]:#__create_return_order(order)__create_refund(order, order.wallet_amount, 'Order #{0} is Lost in Transit'.format(order.id))order.statusDescription = "Lost in Transit Refunded"elif order.status in [OrderStatus.DOA_CERT_INVALID, OrderStatus.DOA_CERT_VALID, OrderStatus.DOA_RECEIVED_DAMAGED, OrderStatus.DOA_LOST_IN_TRANSIT] :if order.status != OrderStatus.DOA_LOST_IN_TRANSIT:__create_return_order(order)__create_refund(order, 0, 'This should be unreachable')order.statusDescription = "DOA Refunded"elif order.status in [OrderStatus.RET_PRODUCT_UNUSABLE, OrderStatus.RET_PRODUCT_USABLE, OrderStatus.RET_RECEIVED_DAMAGED, OrderStatus.RET_LOST_IN_TRANSIT] :if order.status != OrderStatus.RET_LOST_IN_TRANSIT:__create_return_order(order)__create_refund(order, 0, 'This should be unreachable')order.statusDescription = "Return Refunded"elif order.status in [OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.LOW_INV_PO_RAISED, OrderStatus.LOW_INV_REVERSAL_IN_PROCESS, OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT, OrderStatus.ACCEPTED]:__update_inventory_reservation(order, refund=True)order.statusDescription = "Order Refunded"elif order.status == OrderStatus.CANCEL_REQUEST_CONFIRMED:if order.previousStatus in [OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.LOW_INV_PO_RAISED, OrderStatus.LOW_INV_REVERSAL_IN_PROCESS, OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT, OrderStatus.PAYMENT_FLAGGED, OrderStatus.ACCEPTED]:__update_inventory_reservation(order, refund=True)order.statusDescription = "Order Cancelled on customer request"elif order.previousStatus == OrderStatus.BILLED:__create_refund(order, order.wallet_amount, 'Order #{0} Cancelled on customer request'.format(order.id))order.statusDescription = "Order Cancelled on customer request"elif order.status == OrderStatus.PAYMENT_FLAGGED:__update_inventory_reservation(order, refund=True)order.statusDescription = "Order Cancelled due to payment flagged"# For orders that are cancelled after being billed, we need to scan in the scanned out# inventory item and change availability accordinglyinventoryClient = InventoryClient().get_client()warehouse = inventoryClient.getWarehouse(order.warehouse_id)if warehouse.billingType == BillingType.OURS or warehouse.billingType == BillingType.OURS_EXTERNAL:#Now BILLED orders can also be refunded directly with low inventory cancellationsif order.status in [OrderStatus.BILLED, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_FROM_WH]:__create_refund(order, order.wallet_amount, reason)if order.status in [OrderStatus.BILLED, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_FROM_WH] or (order.status == OrderStatus.CANCEL_REQUEST_CONFIRMED and order.previousStatus in [OrderStatus.BILLED, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_FROM_WH]):lineitem = order.lineitems[0]catalogClient = CatalogClient().get_client()item = catalogClient.getItem(lineitem.item_id)warehouseClient = WarehouseClient().get_client()if warehouse.billingType == BillingType.OURS:if ItemType.SERIALIZED == item.type:for serial_number in str(lineitem.serial_number).split(','):warehouseClient.scanSerializedItemForOrder(serial_number, ScanType.SALE_RET, order.id, order.fulfilmentWarehouseId, 1, order.warehouse_id)else:warehouseClient.scanForOrder(None, ScanType.SALE_RET, lineitem.quantity, order.id, order.fulfilmentWarehouseId, order.warehouse_id)if warehouse.billingType == BillingType.OURS_EXTERNAL:warehouseClient.scanForOursExternalSaleReturn(order.id, lineitem.transfer_price)if order.freebieItemId:warehouseClient.scanfreebie(order.id, order.freebieItemId, 0, ScanType.SALE_RET)order.status = status_transition[order.status]order.statusDescription = OrderStatus._VALUES_TO_NAMES[order.status]order.refund_timestamp = datetime.datetime.now()order.refunded_by = refunded_byorder.refund_reason = reason#to re evaluate the shipping charge if any order is being cancelled.#_revaluate_shiping(order_id)session.commit()return Truedef _revaluate_shiping(orderId):orders = Order.get_by(id = orderId)totalCartVal=0totalshippingCost=0if orders:ordersList = get_orders_for_transaction(orders.transaction_id, orders.customer_id)for order in ordersList:if order.status == OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY or order.shipping_timestamp is not None:returnif order.status not in [OrderStatus.COD_VERIFICATION_FAILED,OrderStatus.CANCELLED_ON_CUSTOMER_REQUEST,OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY]:for line in order.lineitems:totalCartVal = totalCartVal+line.total_priceif totalCartVal<1000:totalshippingCost = 50shippingCostInOrders=0shipUpdateOrder= Noneif totalshippingCost > 0:for order in ordersList:if order.status not in [OrderStatus.COD_VERIFICATION_FAILED,OrderStatus.CANCELLED_ON_CUSTOMER_REQUEST,OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY]:for line in order.lineitems:order.shippingCost = round((line.total_price*totalshippingCost)/totalCartVal, 0)shippingCostInOrders = shippingCostInOrders + order.shippingCostif shipUpdateOrder is None:shipUpdateOrder = orderif shipUpdateOrder is not None:diff = totalshippingCost - shippingCostInOrdersif diff>0:shipUpdateOrder.shippingCost = shipUpdateOrder.shippingCost + diffdef __update_inventory_reservation(order, refund=False):'''Reduce the reservation count for all line items of the given order.'''if refund:if order.wallet_amount > 0:refund_to_wallet(order.customer_id, order.wallet_amount, order.transaction.id, WalletReferenceType.PURCHASE, "Refunded angainst cancellation of Order Id -" + str(order.id))try:inventoryClient = InventoryClient().get_client()for lineitem in order.lineitems:inventoryClient.reduceReservationCount(lineitem.item_id, order.fulfilmentWarehouseId, sourceId, order.id, lineitem.quantity)except:print "Unable to reduce reservation count"def __clone_order(order, should_copy_billing_info, is_cod, reserved=True):current_time = datetime.datetime.now()new_order = Order()new_order.customer_id = order.customer_idnew_order.customer_name = order.customer_namenew_order.customer_city = order.customer_citynew_order.customer_state = order.customer_statenew_order.customer_mobilenumber = order.customer_mobilenumbernew_order.customer_pincode = order.customer_pincodenew_order.customer_address1 = order.customer_address1new_order.customer_address2 = order.customer_address2new_order.customer_email = order.customer_emailnew_order.total_amount = order.total_amountnew_order.gvAmount = order.gvAmountnew_order.total_weight = order.total_weightnew_order.status = OrderStatus.SUBMITTED_FOR_PROCESSINGnew_order.statusDescription = 'Submitted for Processing'new_order.created_timestamp = current_timenew_order.originalOrderId = order.originalOrderId if order.originalOrderId is not None else order.idnew_order.shippingCost = order.shippingCostnew_order.transaction = order.transactionnew_order.cod = is_codnew_order.orderType = order.orderTypefor line_item in order.lineitems:litem = LineItem()litem.item_id = line_item.item_idlitem.productGroup = line_item.productGrouplitem.brand = line_item.brandif line_item.model_number:litem.model_number = line_item.model_numberif line_item.model_name:litem.model_name = line_item.model_nameif line_item.color:litem.color = line_item.colorif line_item.extra_info:litem.extra_info = line_item.extra_infolitem.quantity = line_item.quantitylitem.mrp = line_item.mrplitem.unit_price = line_item.unit_pricelitem.unit_weight = line_item.unit_weightlitem.total_price = line_item.total_pricelitem.total_weight = line_item.total_weightlitem.transfer_price = line_item.transfer_pricelitem.nlc = line_item.nlclitem.dealText = line_item.dealTextlitem.vatRate = line_item.vatRatelitem.order = new_orderif order.insurer > 0:new_order.insurer = order.insurernew_order.insuranceAmount = order.insuranceAmountnewDetail = InsuranceDetailForOrder()oldDetail = InsuranceDetailForOrder.get_by(order_id = order.id)newDetail.dob = oldDetail.dobnewDetail.guardianName = oldDetail.guardianNamenewDetail.order = new_orderif order.dataProtectionInsurer > 0:new_order.dataProtectionInsurer = order.dataProtectionInsurernew_order.dataProtectionAmount = order.dataProtectionAmountdataInsuranceDetail = DataInsuranceDetailForOrder()dataInsuranceDetail.order = new_orderlogistics_client = LogisticsClient().get_client()item_id = new_order.lineitems[0].item_idlogistics_info = logistics_client.getLogisticsInfo(new_order.customer_pincode, item_id, is_cod, PickUpType.COURIER) #TODO: We should be able to pass another flag to suggest ignoring the inventory situation.logistics_info.shippingTime = adjust_delivery_time(current_time, logistics_info.shippingTime)logistics_info.deliveryTime = adjust_delivery_time(current_time, logistics_info.deliveryTime)logistics_info.deliveryDelay = adjust_delivery_time(current_time, (logistics_info.shippingTime + logistics_info.deliveryDelay))new_order.warehouse_id = logistics_info.warehouseIdnew_order.fulfilmentWarehouseId = logistics_info.fulfilmentWarehouseIdnew_order.logistics_provider_id = logistics_info.providerId'''new_order.airwaybill_no = logistics_info.airway_billnonew_order.tracking_id = new_order.airwaybill_no'''new_order.source = order.sourceorder.courier_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryDelay)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)new_order.promised_delivery_time = new_order.expected_delivery_timenew_order.promised_shipping_time = order.promised_shipping_timeif reserved:new_order.expected_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryTime)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)new_order.expected_shipping_time = (current_time + datetime.timedelta(days=logistics_info.shippingTime)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)else:new_order.expected_delivery_time = order.expected_delivery_timenew_order.expected_shipping_time = order.expected_shipping_timeif should_copy_billing_info:new_order.vendorId = order.vendorIdnew_order.invoice_number = order.invoice_numbernew_order.billed_by = order.billed_bynew_order.warehouse_id = order.warehouse_idnew_order.fulfilmentWarehouseId = order.fulfilmentWarehouseIdnew_order.jacket_number = order.jacket_numbernew_order.lineitems[0].serial_number = order.lineitems[0].serial_numbernew_order.lineitems[0].item_number = order.lineitems[0].item_numbernew_order.accepted_timestamp = current_timenew_order.billing_timestamp = current_timenew_order.status = OrderStatus.BILLEDnew_order.statusDescription = 'Order Billed'if new_order.logistics_provider_id != 7 and new_order.airwaybill_no is None:if is_cod and order.total_amount > 1:new_order.airwaybill_no= logistics_client.getEmptyAWB(new_order.logistics_provider_id, DeliveryType.COD)new_order.tracking_id = new_order.airwaybill_noelse:new_order.airwaybill_no= logistics_client.getEmptyAWB(new_order.logistics_provider_id, DeliveryType.PREPAID)new_order.tracking_id = new_order.airwaybill_nosession.commit()else:session.commit()if reserved:inventoryClient = InventoryClient().get_client()inventoryClient.reserveItemInWarehouse(item_id, logistics_info.fulfilmentWarehouseId, sourceId, new_order.id, to_java_date(new_order.created_timestamp), to_java_date(new_order.promised_shipping_time), new_order.lineitems[0].quantity)if order.source == 2:new_order.advanceAmount = order.advanceAmountnew_order.storeId = order.storeIdoldSod = StoreOrderDetail.query.filter(StoreOrderDetail.orderId == order.id).filter(StoreOrderDetail.storeId == order.storeId).first()newSod = StoreOrderDetail()newSod.orderId = new_order.idnewSod.storeId = oldSod.storeIdnewSod.advanceAmount = oldSod.advanceAmountnewSod.approvalCode = oldSod.approvalCodenewSod.cardAmount = oldSod.cardAmountnewSod.cashAmount = oldSod.cashAmountnewSod.cashRefundAmount = oldSod.cashRefundAmountnewSod.cardRefundAmount = oldSod.cardRefundAmountnewSod.edcBank = oldSod.edcBanknewSod.payStatus = oldSod.payStatusnewSod.cardType = oldSod.cardTypesession.commit()if order.source == 3:old_amazon_order = AmazonOrder.get_by(orderId=order.id)amazon_order = AmazonOrder()amazon_order.orderId = new_order.idamazon_order.amazonOrderCode = old_amazon_order.amazonOrderCodeamazon_order.amazonOrderItemCode = old_amazon_order.amazonOrderItemCodeamazon_order.transactionId = old_amazon_order.transactionIdamazon_order.item_id= old_amazon_order.item_idamazon_order.status= old_amazon_order.statusamazon_order.purchaseDateOnAmazon= old_amazon_order.purchaseDateOnAmazonsession.commit()if order.source == 6:old_ebay_order = EbayOrder.get_by(orderId=order.id)ebay_order = EbayOrder()ebay_order.orderId = new_order.idebay_order.salesRecordNumber = old_ebay_order.salesRecordNumberebay_order.paisaPayId = old_ebay_order.paisaPayIdebay_order.ebayListingId = old_ebay_order.ebayListingIdebay_order.subsidyAmount= old_ebay_order.subsidyAmountebay_order.ebayTxnDate= old_ebay_order.ebayTxnDateebay_order.transactionId= old_ebay_order.transactionIdebay_order.listingName= old_ebay_order.listingNamesession.commit()if order.source == 7:old_snapdeal_order = SnapdealOrder.get_by(orderId=order.id)snapdeal_order = SnapdealOrder()snapdeal_order.orderId = new_order.idsnapdeal_order.subOrderId = old_snapdeal_order.subOrderIdsnapdeal_order.referenceCode = old_snapdeal_order.referenceCodesnapdeal_order.productName = old_snapdeal_order.productNamesnapdeal_order.listingPrice = old_snapdeal_order.listingPricesnapdeal_order.snapdealTxnDate = old_snapdeal_order.snapdealTxnDatesession.commit()if order.source == 8:old_flipkart_order = FlipkartOrder.get_by(orderId=order.id)flipkart_order = FlipkartOrder()flipkart_order.orderId = new_order.idflipkart_order.subOrderId = old_flipkart_order.subOrderIdflipkart_order.referenceCode = old_flipkart_order.referenceCodeflipkart_order.productName = old_flipkart_order.productNameflipkart_order.listingPrice = old_flipkart_order.listingPriceflipkart_order.snapdealTxnDate = old_flipkart_order.snapdealTxnDatesession.commit()attributes = Attribute.query.filter(Attribute.orderId == order.id).all()if attributes:for attribute in attributes:newattribute = Attribute()newattribute.orderId = new_order.idnewattribute.name = attribute.namenewattribute.value = attribute.valuesession.commit()return new_orderdef __create_return_order(order):ret_order = ReturnOrder(order)return ret_orderdef __create_refund(order, refundAmount, reason="Order Refunded"):if order.wallet_amount > 0:refund_to_wallet(order.customer_id, refundAmount, order.transaction.id, WalletReferenceType.PURCHASE, reason)if order.net_payable_amount > 0:payment_client = PaymentClient().get_client()payment_client.createRefund(order.id, order.transaction.id, order.net_payable_amount)returndef __get_order_address(order):address = order.customer_name + "\n" + order.customer_address1 + "\n"if order.customer_address2:address = address + order.customer_address2 + "\n"address = address + order.customer_city + "\n"address = address + order.customer_state + "\n"address = address + "PIN " + order.customer_pincode + "\n"address = address + "Phone: " + order.customer_mobilenumberreturn addressdef __get_order_address_html(order):address = order.customer_name + ", " + order.customer_address1 + ", "if order.customer_address2:address = address + order.customer_address2 + ", "address = address + order.customer_city + ", "address = address + order.customer_state + ", "address = address + "PIN " + order.customer_pincode + "."return addressdef __get_store_address(store):address = store.name + "\n" + store.line1 + "\n"if store.line2:address = address + store.line2 + "\n"address = address + store.city + "\n"address = address + store.state + "\n"address = address + "PIN - " + store.pin + "\n"if store.phone:address = address + "Phone - " + store.phone + "\n"address = address + "Store timings - 11AM to 8PM (7 days)\n"return addressdef __get_store_address_html(store):address = store.name + "<br>" + store.line1 + "<br>"if store.line2:address = address + store.line2 + "<br>"address = address + store.city + "<br>"address = address + store.state + "<br>"address = address + "PIN - " + store.pin + "<br>"if store.phone:address = address + "Phone - " + store.phone + "<br>"address = address + "Store timings - 7 days: 11AM to 8PM (7 days)<br>"return addressdef __get_hotspot_store_address_html(store):address = store.line1 + ", "if store.line2:address = address + store.line2 + ", "address = address + store.city + ", "address = address + store.state + ", "address = address + "PIN - " + store.pinreturn addressdef __generate_return_advice(order, warehouse, provider, filename):if warehouse.id == 7:executive = 'Shiv Kumar'else:executive = 'Dinesh Kumar'pdf = Canvas(filename)pdf.setFont('Times-Bold',16)address_text = pdf.beginText(inch, PAGE_HEIGHT - inch)address_text.textLine("To")address_text.textLine(executive)for line in warehouse.location.split("\n"):address_text.textLine(line)address_text.textLine("PIN " + warehouse.pincode)pdf.drawText(address_text)pdf.setFont('Times-Roman',12)order_text = pdf.beginText(inch, PAGE_HEIGHT - 4 * inch)for detail in provider.details:if detail.deliveryType == DeliveryType.PREPAID and detail.logisticLocation == warehouse.logisticsLocation :order_text.textLine("Pickup CODE: " + detail.accountNo)lineitem = order.lineitems[0]order_text.textLine("Content : " + lineitem.brand + " " + str(lineitem.model_number) + " " + str(lineitem.color))order_text.textLine("Declared Value: Rs. " + str(order.total_amount))order_text.textLine("Order ID : " + str(order.id))pdf.drawText(order_text)pdf.showPage()pdf.save()return filenamedef __coord(self, x, y, unit=1):"""# http://stackoverflow.com/questions/4726011/wrap-text-in-a-table-reportlabHelper class to help position flowables in Canvas objects"""x, y = x * unit, PAGE_HEIGHT - y * unitreturn x, ydef __generate_return_transaction_invoice(returnOrders, warehouse, provider, filename):ReturnPickupRequestif warehouse.id == 7:executive = 'Varun Patiyal'else:executive = 'Deepak Kumar'pdf = Canvas(filename)styles = getSampleStyleSheet()address = """ <font size="9">To<br/><br/>%s<br/>"""%(executive)for line in warehouse.location.split("\n"):address = address +"""%s<br/>"""%(line)address = address +"""PIN %s<br>"""%(warehouse.pincode)address = address +"""</font>"""p = Paragraph(address, styles["Normal"])p.wrapOn(pdf, PAGE_WIDTH, PAGE_HEIGHT)p.drawOn(pdf, *__coord(18, 40, mm))returnPickupReq = ReturnPickupRequest.get_by(id=returnOrders[0].logisticsRequestId)order_number = '<font size="14"><b>Return Pickup Request No:- %s </b></font>' % returnPickupReq.pickupRequestNop = Paragraph(order_number, styles["Normal"])p.wrapOn(pdf, PAGE_WIDTH, PAGE_HEIGHT)p.drawOn(pdf, *__coord(18, 50, mm))data = []data.append(["Content", "Quantity", "Declared Value: Rs.", "Order ID", "Return Ticket Id"])for returnOrder in returnOrders:lineitem = returnOrder.lineitemrow = []row.append(str(lineitem))row.append(returnOrder.returnQuantity)row.append(returnOrder.returnQuantity*lineitem.unit_price)row.append(returnOrder.orderId)row.append(returnOrder.returnTransaction.id)data.append(row)t = Table(data, 1.5 * inch)t.setStyle(TableStyle([('INNERGRID', (0,0), (-1,-1), 0.25, colors.black),('BOX', (0,0), (-1,-1), 0.25, colors.black)]))t.wrapOn(pdf, PAGE_WIDTH, PAGE_HEIGHT)t.drawOn(pdf, *__coord(18, 85, mm))pdf.showPage()pdf.save()return filenamedef __push_store_collection_to_hotspot(order, ctype, cashamount, cardamount):ts = datetime.datetime.now()store = get_hotspot_store(order.storeId, "")soc = StoreOrderCollection()soc.hotspotId = store.hotspotIdsoc.orderId = order.idsoc.collectionType = ctypesoc.advanceAmount = int(cashamount + cardamount)soc.productName = str(order.lineitems[0])soc.addedAt = tssoc.pushedToOcr = Falsesoc.cash = int(cashamount)soc.card = int(cardamount)session.commit()try:rcs = StoreOrderCollection.query.filter(StoreOrderCollection.pushedToOcr == False).all()for cs in rcs:#SaholicAdvanceTransfer(xs:string Store, xs:string OrderID, xs:string Product, xs:string CollectionType, xs:decimal AdvanceAmount, xs:decimal CashAmount, xs:decimal CardAmount, xs:string Time, xs:string Date, )resp = get_store_account_client().service.SaholicAdvanceTransfer(cs.hotspotId,str(cs.orderId),cs.productName,cs.collectionType,float(cs.advanceAmount),float(cs.cash),float(cs.card),cs.addedAt.strftime("%H%M%S"),cs.addedAt.strftime("%Y%m%d"))print respif "Saved Successfully" in resp:cs.pushedToOcr = Truecs.pushedAt = datetime.datetime.now()session.commit()elif "Error in Saving Data" in resp:mail_html("cnc.center@shop2020.in", "5h0p2o2o", ["kshitij.sood@shop2020.in", "rajneesh.arora@shop2020.in"], "Problem while pushing store collection to OCR", resp, [])else:mail_html("cnc.center@shop2020.in", "5h0p2o2o", ["kshitij.sood@shop2020.in", "amit.gupta@shop2020.in", "rajneesh.arora@shop2020.in"], "Problem while pushing store collection to OCR", resp, [])except:print "Problem while pushing to ocr"def __push_collection_to_hotspot(order, type, storeOrder = False):try:storeName = '109'if storeOrder:store = get_hotspot_store(order.storeId, "")storeName = store.hotspotIdstoreName = '109'else:logistics_client = LogisticsClient().get_client()store = logistics_client.getPickupStore(order.pickupStoreId)storeName = store.hotspotIdpayment_mode = get_order_attribute_value(order.id, "PAYMENT_MODE")if type == "SALE":if storeOrder:amount = int(order.advanceAmount)ts = order.created_timestampelse:amount = int(order.total_amount-order.gvAmount)ts = order.delivery_timestampif type == "SALE RETURN":if storeOrder:amount = -int(order.advanceAmount)else:amount = -int(order.total_amount-order.gvAmount)ts = order.refund_timestampcash_int = 0card_int = 0if payment_mode == "Cash":cash_int = amountcard_int = 0if payment_mode == "Card":cash_int = 0card_int = amount#SaholicDataTransfer(xs:string store, xs:string orderno, xs:string Type, xs:int cash, xs:int hdfc, xs:int date, xs:int time, )resp = get_store_account_client().service.SaholicDataTransfer(storeName,str(order.id),type,cash_int,card_int,int(ts.strftime("%Y%m%d")),int(ts.strftime("%H%M%S")))print respif "Saved Successfully" in resp:return Trueelif "Error in Saving Data" in resp:return Falseelse:return Falseexcept Exception as e:print ereturn Falsedef get_return_orders(warehouse_id, from_date, to_date):query = ReturnOrder.query.filter_by(processedStatus = False)if warehouse_id != -1:query = query.filter_by(warehouseId = warehouse_id)if from_date:query = query.filter(ReturnOrder.createdAt >from_date)if to_date:query = query.filter(ReturnOrder.createdAt < to_date)return [return_order.to_thrift_object() for return_order in query.all()]def get_all_return_orders(onlyNotProcessed, from_date, to_date):query = ReturnOrder.queryif onlyNotProcessed:query = query.filter_by(processedStatus = False)if from_date:query = query.filter(ReturnOrder.createdAt >= from_date)if to_date:query = query.filter(ReturnOrder.createdAt <= to_date)return [return_order.to_thrift_object() for return_order in query.all()]def get_return_order(id):ret_order = ReturnOrder.get_by(orderId = id)if ret_order is None:raise TransactionServiceException(116, "No return order found for the given order id")return ret_order.to_thrift_object()def process_return(ret_order_id):ret_order = ReturnOrder.get_by(orderId = ret_order_id)if ret_order is None:raise TransactionServiceException(116, "No return order found for the given order id")ret_order.processedStatus = Trueret_order.processedAt = datetime.datetime.now()session.commit()def update_orders_as_PORaised(itemIdQuantityMap, purchaseOrderId, warehouseId):"""Updates orders as PO raised. Also updates purchase order id in orders. Pass a map of items mapped tothe quantities for which the PO is raised.Parameters:- itemIdQuantityMap- purchaseOrderId- warehouseId"""query = Order.query.with_lockmode("update").filter_by(warehouse_id=warehouseId)query = query.filter(or_(Order.status == OrderStatus.SUBMITTED_FOR_PROCESSING, Order.status == OrderStatus.INVENTORY_LOW))query = query.filter_by(purchase_order_id=None)query = query.order_by(Order.created_timestamp)pending_orders = query.all()for order in pending_orders:lineitem = order.lineitems[0]if itemIdQuantityMap.has_key(lineitem.item_id):if itemIdQuantityMap[lineitem.item_id] >= lineitem.quantity:order.status = OrderStatus.LOW_INV_PO_RAISEDorder.statusDescription = 'In Process'order.purchase_order_id = purchaseOrderIditemIdQuantityMap[lineitem.item_id] -= lineitem.quantitysession.commit()def update_weight(order_id, weight):'''Update the weight of order'''order = get_order(order_id)order.total_weight = weightlineitem = order.lineitems[0]lineitem.total_weight = weightlineitem.unit_weight = weightsession.commit()return orderdef change_courier_provider(order_id, provider_id):order = get_order(order_id)if order.status not in [OrderStatus.COD_VERIFICATION_PENDING, OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.ACCEPTED, OrderStatus.BILLED]:raise TransactionServiceException(121, "This order has already been processed. Please seek help from engineering.")if order.logistics_provider_id == provider_id:raise TransactionServiceException(121, "Provider Id entered by you is same as provider assigned to order.")logistics_client = LogisticsClient().get_client()if provider_id != 7 and provider_id != 46:awb_number = logistics_client.getEmptyAWB(provider_id, order.cod)order.logistics_provider_id = provider_idif provider_id != 7 and provider_id != 46:order.airwaybill_no = awb_numberorder.tracking_id = awb_numbersession.commit()return orderdef change_product(order_id, item_id):'''Ship a product of a different color to the customer.Do nothingorder = get_order(order_id)if order.status not in [OrderStatus.COD_VERIFICATION_PENDING, OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.ACCEPTED, OrderStatus.INVENTORY_LOW, OrderStatus.LOW_INV_PO_RAISED, OrderStatus.LOW_INV_REVERSAL_IN_PROCESS, OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT]:raise TransactionServiceException(120, "This order has already been processed. Please seek help from engineering.")lineitem = order.lineitems[0]catalog_client = CatalogClient().get_client()old_item = catalog_client.getItem(lineitem.item_id)item = catalog_client.getItem(item_id)if old_item.catalogItemId != item.catalogItemId:freebie_order_info_text = "Freebie Order for Order ID"if lineitem.extra_info and freebie_order_info_text in lineitem.extra_info:print "Allowing item change for split Freebie Order"else:raise TransactionServiceException(121, "You can't ship a different item. You can only ship the same item in a different color.")inventoryClient = InventoryClient().get_client()if order.productCondition != ProductCondition.BAD:inventoryClient.updateReservationForOrder(item_id, order.fulfilmentWarehouseId, sourceId, order.id, to_java_date(order.created_timestamp), to_java_date(order.promised_shipping_time), order.lineitems[0].quantity)#inventoryClient.reserveItemInWarehouse(item_id, order.fulfilmentWarehouseId, sourceId, order.id, to_java_date(order.created_timestamp), to_java_date(order.promised_shipping_time), order.lineitems[0].quantity)#__update_inventory_reservation(order)#TODO: Check that this new item has the same pricelineitem.item_id = item_idlineitem.brand = item.brandlineitem.model_name = item.modelNamelineitem.model_number = item.modelNumberlineitem.color = item.colorsession.commit()move_orders_to_correct_warehouse()'''print 'Could not change product'order = get_order(order_id)return orderdef change_warehouse(order_id, warehouse_id):'''Update the warehouse which will be used to fulfil this order.'''order = get_order(order_id)if order.status not in [OrderStatus.COD_VERIFICATION_PENDING, OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.LOW_INV_PO_RAISED, OrderStatus.LOW_INV_REVERSAL_IN_PROCESS, OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT, OrderStatus.ACCEPTED]:raise TransactionServiceException(117, "This order has already been processed. Please seek help from engineering.")if warehouse_id == order.warehouse_id:raise TransactionServiceException(118, "You have selected the current warehouse again. Nothing to do")lineitem = order.lineitems[0]userClient = UserClient().get_client()inventoryClient = InventoryClient().get_client()try:warehouse = inventoryClient.getWarehouse(warehouse_id)except:raise TransactionServiceException(119, "No warehouse with id" + str(warehouse_id))if not warehouse.billingWarehouseId:raise TransactionServiceException(119, "Shifting of warehouse allowed to warehouse with billing support only")# If One gives a billing warehouse for warehouse shift, we should assign order to the GOOD warehouse# present within it with maximum availabilitystateId = -1userClient, isFofo = __is_Fofo(userClient, order.customer_id)if isFofo:stateId = warehouse.stateIdif warehouse.id == warehouse.billingWarehouseId:itemAvailabilityLocation = inventoryClient.getItemAvailabilityAtLocation(lineitem.item_id, sourceId, stateId)if warehouse.billingWarehouseId == itemAvailabilityLocation[2]:billing_warehouse_id=itemAvailabilityLocation[2]vendor_warehouse_id=itemAvailabilityLocation[0]else:#In case movement happens to Lucknow Warehouse move the order to virtual warehouse firstbilling_warehouse_id = warehouse.billingWarehouseIdvendor_warehouse_id = 8489else:vendor_warehouse_id = warehouse_idbilling_warehouse_id=warehouse.billingWarehouseId#if vendorWarehouse is None or vendorWarehouse.billingWarehouseId != warehouse.id:#assign it to first vendorwarehouse available withif order.productCondition != ProductCondition.BAD:inventoryClient.updateReservationForOrder(lineitem.item_id, vendor_warehouse_id, sourceId, order.id, to_java_date(order.created_timestamp), to_java_date(order.promised_shipping_time), lineitem.quantity)#__update_inventory_reservation(order)if order.status == OrderStatus.ACCEPTED:__update_transfer_price(order, vendor_warehouse_id)order.warehouse_id = billing_warehouse_idorder.fulfilmentWarehouseId = vendor_warehouse_idsession.commit()return orderdef __update_transfer_price(order, warehouse_id):lineitem = order.lineitems[0]inventory_client = InventoryClient().get_client()warehouse = inventory_client.getWarehouse(warehouse_id)item_pricing = inventory_client.getItemPricing(lineitem.item_id, warehouse.vendor.id)lineitem.transfer_price = item_pricing.transferPricelineitem.nlc = item_pricing.nlcdef add_delay_reason(order_id, reason, further_delay, delayReasonText):'''Adds a delay reason to the order and updates the expected delivery time.'''order = get_order(order_id)try:order.delay_reason = DelayReason._VALUES_TO_NAMES[reason]order.delayReasonText = delayReasonTextactual_delivery_delay = adjust_delivery_time(order.expected_delivery_time, further_delay)order.expected_delivery_time = order.expected_delivery_time + datetime.timedelta(days=actual_delivery_delay)actual_shipping_delay = adjust_delivery_time(order.expected_shipping_time, further_delay)order.expected_shipping_time = order.expected_shipping_time + datetime.timedelta(days=actual_shipping_delay)if order.courier_delivery_time:order.courier_delivery_time = order.courier_delivery_time + datetime.timedelta(days=adjust_delivery_time(order.courier_delivery_time, further_delay))else:order.courier_delivery_time = order.expected_delivery_time + datetime.timedelta(days=adjust_delivery_time(order.expected_delivery_time, further_delay))session.commit()exist = TransactionRequiringExtraProcessing.query.filter_by(transaction_id = order.transaction_id).first()if not exist:try:transaction_requiring_extra_processing = TransactionRequiringExtraProcessing()transaction_requiring_extra_processing.category = 'DELAYED_DELIVERY'transaction_requiring_extra_processing.transaction_id = order.transaction_idsession.commit()except Exception as e:print 'Could not persist transaction id: ' + str(order.transaction_id) + ' for further processing due to: ' + str(e)return Trueexcept:print sys.exc_info()[0]return Falsedef reconcile_cod_collection(collected_amount_map, xferBy, xferTxnId, xferDate):unprocessed_awbs = {}for awb, amount in collected_amount_map.iteritems():try:orders = Order.query.filter_by(airwaybill_no=awb).all()except NoResultFound:unprocessed_awbs[awb] = "No order was found for the given AWB: " + awbcontinueorder = orders[0]totalOrdersAmount = 0for order in orders:totalOrdersAmount = totalOrdersAmount + order.net_payable_amountif order.cod_reconciliation_timestamp:#This order has been processed already! This may be a re-run. Let's allow other orders to be processed.continueif order.status < OrderStatus.DELIVERY_SUCCESS:#Order has not been delivered yet. No way we can receive the payment.unprocessed_awbs[awb] = "Payment has been received for order: " + str(order.id) + " before it has been delivered"continue##As per ticket #743 if amount difference less than 0.5 we should reconcileif abs(amount - totalOrdersAmount) > 0.5:#Received amount is less than or more than the order amount. Mustn't let the user proceed.unprocessed_awbs[awb] = "Payment of Rs. " + str(amount) + " has been received against the total value of Rs. " + str(totalOrdersAmount)continuetry:payment_client = PaymentClient().get_client()payment_client.partiallyCapturePayment(order.transaction.id, amount, xferBy, xferTxnId, xferDate)except Exception:unprocessed_awbs[awb] = "We were unable to partially capture payment for order id " + str(order.id) + ", AWB: " + awbcontinue#Payment has been recorded now. We can update the order peacefully.remittance = CodCourierPaymentRemittance()remittance.airwayBillNo = awbremittance.collectionReference = xferTxnIdremittance.amount = amountremittance.settledAt = to_py_date(xferDate)remittance.provider_id = order.logistics_provider_idfor order in orders:order.cod_reconciliation_timestamp = datetime.datetime.now()session.commit()return unprocessed_awbsdef get_transactions_requiring_extra_processing(category):"""Returns the list of transaction ids that require some extra processing andwhich belong to a particular category. This is currently used by CRMapplication. If no such transaction ids are present, it returns an empty list."""query = TransactionRequiringExtraProcessing.queryif category is not None:query = query.filter_by(category = ExtraTransactionProcessingType._VALUES_TO_NAMES.get(category))return [a.transaction_id for a in query.all()]def mark_transaction_as_processed(transactionId, category):"""Marks a particular transaction as processed for a particular cateogory.It essentially deletes the transaction id record for a particularprocessing type category (if present) from DB.This is currently used by CRM application."""TransactionRequiringExtraProcessing.query.filter_by(transaction_id = transactionId).filter_by(category = ExtraTransactionProcessingType._VALUES_TO_NAMES.get(category)).delete()session.commit()def get_item_wise_risky_orders_count():"""Returns a map containing the number of risky orders keyed by item id. A risky orderis defined as one whose shipping date is about to expire."""item_wise_risky_orders_count = {}shipping_cutoff_time = (datetime.datetime.now() + datetime.timedelta(days = 1)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)orders = Order.query.filter(Order.status.in_(tuple([OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.ACCEPTED]))).filter(Order.expected_shipping_time <= shipping_cutoff_time).all()for order in orders:for lineitem in order.lineitems:quantity = lineitem.quantityif item_wise_risky_orders_count.has_key(lineitem.item_id):quantity = quantity + item_wise_risky_orders_count[lineitem.item_id]item_wise_risky_orders_count[lineitem.item_id] = quantityreturn item_wise_risky_orders_countdef update_shipment_address(order_id, address_id):"""Updates shipment address of an order. Delivery and shipping date estimatesetc. are also updated here.Throws TransactionServiceException in case address change is notpossible due to certain reasons such as new pincode in address isnot serviceable etc.Parameters:- orderId- addressId"""user_client = UserClient().get_client()address = user_client.getAddressById(address_id)order = get_order(order_id)type = DeliveryType.PREPAIDif order.cod:type = DeliveryType.CODlogistics_client = LogisticsClient().get_client()logistics_info = logistics_client.getLogisticsEstimation(order.lineitems[0].item_id, address.pin, type)# Check for new estimate. Raise exception if new address is not serviceableif logistics_info.deliveryTime == -1:raise TransactionServiceException(1, 'Location not serviceable')# COD services are not available everywhereif order.cod:if not logistics_info.codAllowed:raise TransactionServiceException(2, 'COD service not available')if logistics_info.providerId != order.logistics_provider_id:logistics_info = logistics_client.getLogisticsInfo(address.pin, order.lineitems[0].item_id, type, PickUpType.COURIER)#Start:- Added by Manish Sharma for FedEx Integration- Shipment Creation on 31-Jul-2013#order.tracking_id = logistics_info.airway_billno#order.airwaybill_no = logistics_info.airway_billnoif logistics_info.providerId !=7 and logistics_info.providerId !=46:awb_number = logistics_client.getEmptyAWB(logistics_info.providerId, type)order.tracking_id = awb_numberorder.airwaybill_no = awb_number#End:- Added by Manish Sharma for FedEx Integration- Shipment Creation on 31-Jul-2013order.logistics_provider_id = logistics_info.providerIdorder.otg = logistics_info.otgAvailablecurrent_time = datetime.datetime.now()logistics_info.deliveryTime = adjust_delivery_time(current_time, logistics_info.deliveryTime)logistics_info.shippingTime = adjust_delivery_time(current_time, logistics_info.shippingTime)logistics_info.deliveryDelay = adjust_delivery_time(current_time, (logistics_info.shippingTime+logistics_info.deliveryDelay))order.customer_name = address.nameorder.customer_pincode = address.pinorder.customer_address1 = address.line1order.customer_address2 = address.line2order.customer_city = address.cityorder.customer_state = address.stateorder.customer_mobilenumber = address.phoneif order.cod:order.expected_shipping_time = (current_time + datetime.timedelta(days=logistics_info.shippingTime)).replace(hour=COD_SHIPPING_CUTOFF_TIME, minute=0, second=0)order.expected_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryTime)).replace(hour=COD_SHIPPING_CUTOFF_TIME, minute=0, second=0)order.courier_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryDelay)).replace(hour=COD_SHIPPING_CUTOFF_TIME, minute=0, second=0)else:order.expected_shipping_time = (current_time + datetime.timedelta(days=logistics_info.shippingTime)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)order.expected_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryTime)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)order.courier_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryDelay)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)order.promised_shipping_time = order.expected_shipping_timeorder.promised_delivery_time = order.expected_delivery_timesession.commit()def convert_store_to_normal(orderId):"""This method is used to convert a pickup in store order into a normal one."""order = get_order(orderId)deliveryType = DeliveryType.PREPAIDif order.cod:deliveryType = DeliveryType.CODlogistics_client = LogisticsClient().get_client()logistics_info = logistics_client.getLogisticsEstimation(order.lineitems[0].item_id, order.customer_pincode, deliveryType)print "******"print "got provider : " + str(logistics_info.providerId)print "order provider : " + str(order.logistics_provider_id)print "delivery time : " + str(logistics_info.deliveryTime)print "codAllowed : " + str(logistics_info.codAllowed)print "******"# Check for new estimate. Raise exception if new address is not serviceableif logistics_info.deliveryTime == -1:raise TransactionServiceException(1, 'Location not serviceable')# COD services are not available everywhereif order.cod:if not logistics_info.codAllowed:raise TransactionServiceException(2, 'COD service not available')logistics_info.airway_billno = logistics_client.getEmptyAWB(logistics_info.providerId, deliveryType)order.tracking_id = logistics_info.airway_billnoorder.airwaybill_no = logistics_info.airway_billnoorder.logistics_provider_id = logistics_info.providerIdorder.pickupStoreId = 0session.commit()return Truedef mark_order_cancellation_request_received(orderId):"""Mark order as cancellation request received. If customer sends request of cancellation ofa particular order, this method will be called. It will just change status of the orderdepending on its current status. It also records the previous status, so that we can moveback to that status if cancellation request is denied.Parameters:- orderId"""status_transition = {OrderStatus.COD_VERIFICATION_PENDING : OrderStatus.CANCEL_REQUEST_RECEIVED,OrderStatus.SUBMITTED_FOR_PROCESSING : OrderStatus.CANCEL_REQUEST_RECEIVED,OrderStatus.INVENTORY_LOW : OrderStatus.CANCEL_REQUEST_RECEIVED,OrderStatus.LOW_INV_PO_RAISED : OrderStatus.CANCEL_REQUEST_RECEIVED,OrderStatus.LOW_INV_REVERSAL_IN_PROCESS : OrderStatus.CANCEL_REQUEST_RECEIVED,OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT : OrderStatus.CANCEL_REQUEST_RECEIVED,OrderStatus.ACCEPTED : OrderStatus.CANCEL_REQUEST_RECEIVED,OrderStatus.BILLED : OrderStatus.CANCEL_REQUEST_RECEIVED,OrderStatus.PAYMENT_FLAGGED : OrderStatus.CANCEL_REQUEST_RECEIVED}order = get_order(orderId)if order.status not in status_transition.keys():raise TransactionServiceException(114, "This order can't be considered for cancellation")order.previousStatus = order.statusorder.status = OrderStatus.CANCEL_REQUEST_RECEIVEDorder.statusDescription = "Cancellation request received from user"session.commit()def mark_order_as_lost_in_transit(orderId):"""Parameters:- orderId"""order = get_order(orderId)if order.status not in [OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY, OrderStatus.REACHED_DESTINATION_CITY, OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE]:raise TransactionServiceException(115, "This order can't be marked as lost in transit")order.status = OrderStatus.LOST_IN_TRANSITorder.statusDescription = "Lost in Transit"session.commit()def mark_transaction_as_payment_flag_removed(transactionId):"""If we and/or payment gateway has decided to accept the payment, this method needs to be called.Changed transaction and all orders status to payment accepted.Parameters:- transactionId"""transaction = get_transaction(transactionId)transaction.status = TransactionStatus.AUTHORIZEDfor order in transaction.orders:order.status = OrderStatus.SUBMITTED_FOR_PROCESSINGorder.statusDescription = "Submitted to warehouse"session.commit()def refund_transaction(transactionId, refundedBy, reason):"""This method is called when a flagged payment is deemed unserviceable and the corresponding ordersneed to be cancelledParameters:- transactionId"""transaction = get_transaction(transactionId)transaction.status = TransactionStatus.FAILEDfor order in transaction.orders:if order.status in refund_status_transition.keys():refund_order(order.id, refundedBy, reason)session.commit()def mark_order_cancellation_request_denied(orderId):"""If we decide to not to cancel order, we will move the order to previous status.Parameters:- orderId"""order = get_order(orderId)order.status = order.previousStatusorder.previousStatus = Noneorder.statusDescription = "Cancellation request denied"session.commit()def mark_order_cancellation_request_confirmed(orderId):"""If we decide to to cancel order, CRM will call this method to move the status of order tocancellation request confirmed. After this OM will be able to cancel the order.Parameters:- orderId"""order = get_order(orderId)order.status = OrderStatus.CANCEL_REQUEST_CONFIRMEDorder.statusDescription = "Cancellation request confirmed"#session.commit()refund_order(order.id, "crm-team", "As per Customer's Request")@memoized(3600)def __is_Fofo(userClient, user_id):if not userClient or not userClient.isAlive():userClient = UserClient().get_client()return userClient, userClient.getPrivateDealUser(user_id).isFofodef move_orders_to_correct_warehouse():completedOrders = []pendingOrders = ""orders = Order.query.filter(Order.status.in_(tuple([OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.LOW_INV_PO_RAISED, OrderStatus.LOW_INV_REVERSAL_IN_PROCESS]))).order_by(Order.promised_shipping_time).all()inventoryClient = InventoryClient().get_client()userClient = UserClient().get_client()warehouses = inventoryClient.getWarehouses(WarehouseType.OURS, InventoryType.GOOD, None, None, None)warehousesMap = {}for warehouse in warehouses:warehousesMap[warehouse.id] = warehousefor order in orders:lineitem = order.lineitems[0]print "order.fulfilmentWarehouseId", order.fulfilmentWarehouseIdfulFilmentWarehouse = warehousesMap.get(order.fulfilmentWarehouseId)if fulFilmentWarehouse is not None:continuetry:itemInventory = inventoryClient.getItemInventoryByItemId(lineitem.item_id)except:inventoryClient = InventoryClient().get_client()itemInventory = inventoryClient.getItemInventoryByItemId(lineitem.item_id)try:fulFilmentWarehouse = inventoryClient.getWarehouse(order.fulfilmentWarehouseId)except:inventoryClient = InventoryClient().get_client()fulFilmentWarehouse = inventoryClient.getWarehouse(order.fulfilmentWarehouseId)for warehouseId, availability in itemInventory.availability.iteritems():warehouse = warehousesMap.get(warehouseId)if warehouse is None:continueif availability - itemInventory.reserved[warehouseId] >= lineitem.quantity and warehouse.stateId==fulFilmentWarehouse.stateId:try:print "++++" + str(order.id) + "=" + str(order.fulfilmentWarehouseId) + "->"+ str(warehouseId)change_warehouse(order.id, warehouseId)completedOrders.append(order.id)except:traceback.print_exc()print "++++" + str(order.id)pendingOrders = pendingOrders + str(order.id) + "|"breakif len(completedOrders)==0 and len(pendingOrders)==0:return "No Order To Move"elif len(completedOrders)>0 and len(completedOrders) == len(orders):return "Completed"elif len(pendingOrders)>0:return pendingOrderselse:return "No Order To Move"def get_slipped_sipping_date_orders():return Order.query.filter(Order.status.in_(tuple([OrderStatus.COD_VERIFICATION_PENDING, OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.LOW_INV_PO_RAISED, OrderStatus.LOW_INV_REVERSAL_IN_PROCESS, OrderStatus.ACCEPTED, OrderStatus.BILLED]))).filter(Order.promised_shipping_time <= datetime.datetime.now()).order_by(Order.promised_shipping_time).all()def get_cancelled_orders(cancelDateFrom, cancelDateTo):return Order.query.filter(Order.status == OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY).filter(Order.refund_timestamp >= cancelDateFrom).filter(Order.refund_timestamp <= cancelDateTo).all()def mark_orders_as_po_raised(vendorId, itemId, quantity, estimate, isReminder):if isReminder:statuses = tuple([OrderStatus.LOW_INV_PO_RAISED_TIMEOUT, OrderStatus.LOW_INV_REVERSAL_TIMEOUT])else:statuses = tuple([OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW])orders = Order.query.filter(Order.status.in_(statuses)).order_by(Order.expected_shipping_time).all()for order in orders:lineitem = order.lineitems[0]if quantity >= lineitem.quantity and itemId == lineitem.item_id:if estimate > 0:add_delay_reason(order.id, DelayReason.OTHERS, estimate)order.status = OrderStatus.LOW_INV_PO_RAISEDorder.statusDescription = "PO Raised"quantity = quantity - lineitem.quantitystore_inventory_action(order, itemId, HotspotAction.PO_RAISED, estimate, lineitem.quantity)session.commit()def mark_orders_as_reversal_initiated(vendorId, itemId, quantity, estimate, isReminder):if isReminder:statuses = tuple([OrderStatus.LOW_INV_PO_RAISED_TIMEOUT, OrderStatus.LOW_INV_REVERSAL_TIMEOUT])else:statuses = tuple([OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW])orders = Order.query.filter(Order.status.in_(statuses)).order_by(Order.expected_shipping_time).all()for order in orders:lineitem = order.lineitems[0]if quantity >= lineitem.quantity and itemId == lineitem.item_id:if estimate > 0:add_delay_reason(order.id, DelayReason.OTHERS, estimate)order.status = OrderStatus.LOW_INV_REVERSAL_IN_PROCESSorder.statusDescription = "Reversal Initiated"quantity = quantity - lineitem.quantitystore_inventory_action(order, itemId, HotspotAction.REVERSAL_INITIATED, estimate, lineitem.quantity)session.commit()def mark_orders_as_not_available(vendorId, itemId, quantity, estimate, isReminder):if isReminder:statuses = tuple([OrderStatus.LOW_INV_PO_RAISED_TIMEOUT, OrderStatus.LOW_INV_REVERSAL_TIMEOUT])else:statuses = tuple([OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW])orders = Order.query.filter(Order.status.in_(statuses)).order_by(Order.expected_shipping_time).all()for order in orders:lineitem = order.lineitems[0]if quantity >= lineitem.quantity and itemId == lineitem.item_id:order.status = OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOTorder.statusDescription = "Not Available"quantity = quantity - lineitem.quantitystore_inventory_action(order, itemId, HotspotAction.NOT_AVAILABLE, estimate, lineitem.quantity)session.commit()def store_inventory_action(order, itemId, hotspotAction, estimate, quantity):orderInv = OrderInventory.get_by(order_id=order.id)if not orderInv:orderInv = OrderInventory()orderInv.order = orderorderInv.hotspotAction = hotspotActionorderInv.estimate = estimateorderInv.itemId = itemIdorderInv.timestamp = datetime.datetime.now()orderInv.quantity = quantity'''def mark_orders_as_timeout(vendorId):ret_timeouts = {}orderInvs = OrderInventory.query.all()for orderInv in orderInvs:if orderInv.timestamp + timedelta(days=orderInv.estimate) < datetime.datetime.now():if not ret_timeouts.has_key(orderInv.itemId):timeout = TimeoutSummary()ret_timeouts[orderInv.itemId] = timeoutelse:timeout = ret_timeouts.get(orderInv.itemId)if orderInv.hotspotAction == HotspotAction.PO_RAISED and orderInv.order.status == OrderStatus.LOW_INV_PO_RAISED:if timeout.poRaised:timeout.poRaised += 1else:timeout.poRaised = 1if timeout.poEstimate:timeout.poEstimate += orderInv.estimateelse:timeout.poEstimate = orderInv.estimateorderInv.order.status = OrderStatus.LOW_INV_PO_RAISED_TIMEOUTorderInv.order.statusDescription = "PO Raised Timeout"elif orderInv.hotspotAction == HotspotAction.REVERSAL_INITIATED and orderInv.order.status == OrderStatus.LOW_INV_REVERSAL_IN_PROCESS:if timeout.reversalInitiated:timeout.reversalInitiated += 1else:timeout.reversalInitiated = 1if timeout.reversalEstimate:timeout.reversalEstimate += orderInv.estimateelse:timeout.reversalEstimate = orderInv.estimateorderInv.order.status = OrderStatus.LOW_INV_REVERSAL_TIMEOUTorderInv.order.statusDescription = "Reversal Initiated Timeout"else:orderInv.delete()session.commit()return ret_timeouts'''def mark_orders_as_timeout(vendorId):ret_timeouts = {}orderInvs = OrderInventory.query.all()for orderInv in orderInvs:if not ret_timeouts.has_key(orderInv.itemId):timeout = TimeoutSummary()ret_timeouts[orderInv.itemId] = timeoutelse:timeout = ret_timeouts.get(orderInv.itemId)if orderInv.hotspotAction == HotspotAction.PO_RAISED and orderInv.order.status == OrderStatus.LOW_INV_PO_RAISED:if timeout.poRaised:timeout.poRaised += 1else:timeout.poRaised = 1if timeout.poEstimate:timeout.poEstimate = max(orderInv.estimate, timeout.poEstimate)else:timeout.poEstimate = orderInv.estimateelif orderInv.hotspotAction == HotspotAction.REVERSAL_INITIATED and orderInv.order.status == OrderStatus.LOW_INV_REVERSAL_IN_PROCESS:if timeout.reversalInitiated:timeout.reversalInitiated += 1else:timeout.reversalInitiated = 1if timeout.reversalEstimate:timeout.reversalEstimate = max(orderInv.estimate, timeout.reversalEstimate)else:timeout.reversalEstimate = orderInv.estimateorderInv.order.status = OrderStatus.INVENTORY_LOWorderInv.order.statusDescription = "Low Inventory"orderInv.delete()session.commit()return ret_timeoutsdef get_order_for_awb(awb):orders = Order.query.filter(Order.airwaybill_no==awb).all()if not orders:orders = []return ordersdef get_orders_for_provider_for_status(provider_id, order_status_list):if not provider_id or not order_status_list:raise TransactionServiceException(101, "bad provider id or order status")doa_provider = Falsefor order_status in order_status_list:if order_status in [OrderStatus.DOA_PICKUP_CONFIRMED, OrderStatus.RET_PICKUP_CONFIRMED]:doa_provider = Trueif doa_provider:query = Order.query.filter_by(doa_logistics_provider_id = provider_id).filter(Order.status.in_(order_status_list))else:query = Order.query.filter_by(logistics_provider_id = provider_id).filter(Order.status.in_(order_status_list))return query.all()def get_billed_orders_for_vendor(vendor_id, billing_date_from, billing_date_to):query = Order.query.filter(Order.status != OrderStatus.PAYMENT_PENDING)if vendor_id:query = query.filter_by(vendorId = vendor_id)if billing_date_from:query = query.filter(Order.billing_timestamp >= billing_date_from)if billing_date_to:query = query.filter(Order.billing_timestamp <= billing_date_to)return query.all()def get_billed_orders(vendor_id, onlyVendorNotPaid, billing_date_from, billing_date_to):query = Order.query.filter(Order.billing_timestamp != None)if onlyVendorNotPaid:query = query.filter_by(vendor_paid = False)if vendor_id != -1:query = query.filter_by(vendorId = vendor_id)if billing_date_from:query = query.filter(Order.billing_timestamp >= billing_date_from)if billing_date_to:query = query.filter(Order.billing_timestamp <= billing_date_to)return query.all()def save_bluedart_settlements(map_awb_and_amount):payment_client = PaymentClient().get_client()for awb, amount in map_awb_and_amount.iteritems():order = Order.get_by(airwaybill_no = awb)payment = payment_client.getSuccessfulPaymentForTxnId(order.transaction_id)settlement = PaymentSettlement()settlement.paymentId = payment.paymentIdsettlement.paymentGatewayId = payment.gatewayIdsettlement.netCollection = amountsession.commit()def save_payment_settlements(settlementDate, paymentGatewayId, referenceId, serviceTax, otherCharges, netCollection):originalOrderId = Noneif paymentGatewayId == 4:cod_order = Order.get_by(id = referenceId)if cod_order.originalOrderId:originalOrderId = cod_order.originalOrderIdelse:originalOrderId = referenceIdsettlement = PaymentSettlement()settlement.settlementDate = settlementDatesettlement.paymentGatewayId = paymentGatewayIdif originalOrderId is not None:settlement.originalOrderId = originalOrderIdsettlement.referenceId = referenceIdsettlement.serviceTax = serviceTaxsettlement.otherCharges = otherChargessettlement.netCollection = netCollectionsession.commit()def get_settlement_for_Prepaid(reference_id, is_refund = False):query = PaymentSettlement.query.filter_by(referenceId = reference_id).filter(PaymentSettlement.paymentGatewayId != 4)if is_refund:query = query.filter(PaymentSettlement.netCollection < 0)else:query = query.filter(PaymentSettlement.netCollection > 0)return query.first()def get_settlement_for_Cod(orderId, is_refund = False):query = PaymentSettlement.query.filter_by(originalOrderId = orderId)if is_refund:query = query.filter(PaymentSettlement.netCollection < 0)else:query = query.filter(PaymentSettlement.netCollection > 0)return query.first()def save_ebs_settlement_summary(settlement_id, settlement_date, transaction_date_from, transaction_date_to, amount):summary = EBSSettlementSummary.query.filter_by(settlementId = settlement_id).first()if summary is None:summary = EBSSettlementSummary()summary.settlementId = settlement_idsummary.settlementDate = settlement_datesummary.transactionDateFrom = transaction_date_fromsummary.transactionDateTo = transaction_date_tosummary.amount = amountsummary.detailsUploaded = Falsesession.commit()def get_ebs_settlement_summaries():summaries = EBSSettlementSummary.query.filter_by(detailsUploaded = False).order_by(EBSSettlementSummary.transactionDateFrom).all()summary_map = {}for summary in summaries:transactionDateFrom = str(summary.transactionDateFrom.year) + '-' + str(summary.transactionDateFrom.month) + '-' + str(summary.transactionDateFrom.day)transactionDateTo = str(summary.transactionDateTo.year) + '-' + str(summary.transactionDateTo.month) + '-' + str(summary.transactionDateTo.day)summary_map[summary.settlementId] = "%s to %s" %(transactionDateFrom, transactionDateTo)return summary_mapdef get_ebs_settlement_date(settlement_id):summary = EBSSettlementSummary.get_by(settlementId = settlement_id)if summary:return summary.settlementDatedef mark_ebs_settlement_uploaded(settlement_id):summary = EBSSettlementSummary.get_by(settlementId = settlement_id)if summary:summary.detailsUploaded = Truesession.commit()def get_settlements_by_date(settlement_date_from, settlement_date_to, is_refund):query = PaymentSettlement.queryif settlement_date_from:query = query.filter(PaymentSettlement.settlementDate >= settlement_date_from)if settlement_date_to:query = query.filter(PaymentSettlement.settlementDate <= settlement_date_to)if is_refund is True:query = query.filter(PaymentSettlement.netCollection < 0.0)else:query = query.filter(PaymentSettlement.netCollection > 0.0)return query.all()def get_reshipped_order_ids(order_ids):reshipped_order_ids = []return [order.new_order_id for order in Order.query.filter(Order.new_order_id.in_(order_ids)).all()]def get_shipping_confirmation_email_body(logisticsTxnId, orderList):order = orderList[0]html = """<html><body><div><p>Dear Customer,</p><p>We are pleased to inform that the following items in your order: $master_order_id have been Shipped.Details of your shipment:<br><br><div><table><tr><td colspan="8"><hr /></td></tr><tr><td colspan="8" align="left"><b>Order Details</b></td></tr><tr><td colspan="8"><hr /></td></tr><tr><th width="100">Sub Order Id</th><th>Product Name</th><th width="100">Quantity</th><th width="100">Unit Price</th><th width="100">Amount</th><th width="100">Insurance Amount</th><th width="100">OTG Covered</th><th width="100">Freebie Item</th></tr>"""total_amount = 0.0total_shipping = 0.0advanceAmount = 0.0hasOtg = FalsehasFreebie = FalsehasSplitOrder = FalsehasInsurer = FalsesplitOrdersMap = {}for orderObj in orderList:lineitem = orderObj.lineitems[0]lineitem_total_price = round(lineitem.total_price, 2)total_amount += lineitem_total_price + orderObj.shippingCosttotal_shipping += orderObj.shippingCostadvanceAmount += orderObj.advanceAmounthtml += """<tr><td align="center">"""+str(orderObj.id)+"""</td><td>"""+str(lineitem)+"""</td><td align="center">"""+("%.0f" % lineitem.quantity)+"""</td><td align="center">"""+("%.2f" % lineitem.unit_price)+"""</td><td align="center">"""+("%.2f" % lineitem_total_price)+"""</td>"""if orderObj.insurer > 0:hasInsurer = Truetotal_amount += orderObj.insuranceAmounthtml += """<td align="center">"""+("%.2f" % orderObj.insuranceAmount) +"""</td>"""else:html += """<td align="center">0.00</td>"""if orderObj.freebieItemId:hasFreebie = Truecatalog_client = CatalogClient().get_client()item = catalog_client.getItem(orderObj.freebieItemId)html += """<td align="center">"""+item.brand+" "+item.modelName+ " " + item.modelNumber +"""</td>"""else:html += """<td align="center"></td>"""freebieOrderId = get_order_attribute_value(orderObj.id, "freebieOrderId")if freebieOrderId != "":freebieOrder = get_order(freebieOrderId)hasSplitOrder = TruesplitOrdersMap[orderObj.id] = freebieOrderhtml += """</tr>"""html += """<tr><td colspan=8> </td></tr><tr><td colspan=8><hr /></td></tr>"""amount_string = "Total Amount"if advanceAmount > 0:html += """<tr><td colspan="7">Advance Amount</td><td>Rs."""+("%.2f" % advanceAmount)+"""</tr>"""total_amount -= advanceAmountamount_string = "Balance Amount"shipping_string = "Shipping Charges"if total_shipping > 0:html = html + """<tr>\<td colspan=7>"""+shipping_string+"""</td>\<td> Rs. """+("%.2f" % total_shipping)+"""</td>\</tr>"""html += """<tr><td colspan="7">"""+amount_string+"""</td><td>Rs."""+("%.2f" % total_amount)+"""</tr>"""html += """</table></div>The shipment will be delivered to you via $courier_name Courier Service vide AWB# $awb.</p><p>Expected delivery date for your order is $expected_delivery_date.<br/>$otg_text$freebie_text<br/>The product can be delivered to you between business hours of 10am to 6pm.You can Check the current shipment updates for your product online at <a href="www.saholic.com/myaccount">Open Orders</a>.</p><p>For scheduling the delivery of your product at some specific timings, we recommend you to contact the helpline for $courier_name with your complete Airway Bill Number.</p><p>$courier_name: $courier_phone</p><p>Warm Regards,<br />$source_name Team</p></div></body></html>"""logistics_providers = {1: {'name': 'BlueDart', 'phone': '011-66111234'}, 6: {'name': 'RedExpress', 'phone': '8373915813'}, 3: {'name': 'Delhivery', 'phone' : '0124- 4212200'}, 7: {'name': 'FedEx', 'phone' : '0120-4354176'}}provider_name = logistics_providers[order.logistics_provider_id]['name']provider_phone = logistics_providers[order.logistics_provider_id]['phone']lclient = LogisticsClient().get_client()logistics_info = lclient.getLogisticsEstimation(order.lineitems[0].item_id, order.customer_pincode, DeliveryType.PREPAID)dt = datetime.datetime.strptime(str(order.shipping_timestamp), "%Y-%m-%d %H:%M:%S")shipping_date = dt.strftime("%A, %d %B %Y %I:%M%p")new_expected_delivery_timestamp = datetime.datetime.now() + timedelta(adjust_delivery_time(datetime.datetime.now(), (logistics_info.deliveryTime - logistics_info.shippingTime)))if order.source ==6:new_expected_delivery_timestamp = datetime.datetime.now() + timedelta(adjust_delivery_time(datetime.datetime.now(), 3))new_courier_delivery_time = datetime.datetime.now() + timedelta(adjust_delivery_time(datetime.datetime.now(), (logistics_info.deliveryTime - logistics_info.shippingTime - logistics_info.deliveryDelay)))#update new expected timestampfor orderObj in orderList:if orderObj.cod:new_expected_delivery_timestamp = new_expected_delivery_timestamp.replace(hour=COD_SHIPPING_CUTOFF_TIME, minute=0, second=0, microsecond=0)orderObj.courier_delivery_time = new_courier_delivery_time.replace(hour=COD_SHIPPING_CUTOFF_TIME, minute=0, second=0, microsecond=0)else:new_expected_delivery_timestamp = new_expected_delivery_timestamp.replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0, microsecond=0)orderObj.courier_delivery_time = new_courier_delivery_time.replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0, microsecond=0)orderObj.expected_delivery_time = new_expected_delivery_timestampsession.commit()new_expected_delivery_date = new_expected_delivery_timestamp.strftime("%A, %d %B %Y")otg_text = ""if hasOtg:promised_delivery_date = order.promised_delivery_time.strftime("%A, %d %B %Y")if new_expected_delivery_timestamp > order.promised_delivery_time:otg_text = 'Your order is covered under our <a href="http://www.saholic.com/static/on-time-guarantee">On Time Guarantee; We Pay if we Delay.</a> We apologize in advance for the expected delay from our initial promised delivery date of ' + promised_delivery_date + '. Your will receive a Gift Voucher Code at time of delivery based on the actual delay. You can use the same to buy any Mobile, Camera, Laptop, Tablet, Accessory or Mobile/DTH Recharge from our website.'elif new_expected_delivery_timestamp < order.promised_delivery_time:otg_text = 'We are happy to inform you that we expect to deliver your order before time. Your order is covered under our <a href="http://www.saholic.com/static/on-time-guarantee">On Time Guarantee; We Pay if we Delay.</a> Please note, compensation for delay (If Any) will be computed from the initial promised delivery date of ' + promised_delivery_date + '.'else:otg_text = 'Your order is covered under our <a href="http://www.saholic.com/static/on-time-guarantee">On Time Guarantee; We Pay if we Delay.</a> We are committed to deliver your order by our initial promised delivery date of ' + promised_delivery_date + '.'freebie_text = "<br/>"if hasFreebie and not hasSplitOrder:freebie_text = freebie_text + "We have also shipped your freebies with eligible products as promised<br/>"elif not hasFreebie and hasSplitOrder:freebie_text = freebie_text + "We wish to inform you that your freebie item(s): <br/>"for splitOrder in splitOrdersMap.values():freebieLineItem = get_line_items_for_order(splitOrder.id)[0]freebie_text = freebie_text + freebieLineItem.brand + " " + freebieLineItem.model_name + " " + freebieLineItem.model_number + " will be sent as a separate order with OrderId : " + str(splitOrder.id) + " and is expected to be delivered on " + splitOrder.expected_delivery_time.strftime("%A, %d %B %Y")+ "<br/>"elif hasFreebie and hasSplitOrder:freebie_text = freebie_text + "We have also shipped some of your freebies with eligible products as promised and rest freebie item(s) details are given below: <br/>"for splitOrder in splitOrdersMap.values():freebieLineItem = get_line_items_for_order(splitOrder.id)[0]freebie_text = freebie_text + freebieLineItem.brand + " " + freebieLineItem.model_name + " " + freebieLineItem.model_number + " will be sent as a separate order with OrderId : " + str(splitOrder.id) + " and is expected to be delivered on " + splitOrder.expected_delivery_time.strftime("%A, %d %B %Y")+ "<br/>"else:freebie_text = ""info = dict(master_order_id = logisticsTxnId, shipping_datetime = shipping_date, awb = order.airwaybill_no, expected_delivery_date = new_expected_delivery_date, courier_name = provider_name, courier_phone = provider_phone, source_name = source_name, otg_text = otg_text, freebie_text = freebie_text)return Template(html).substitute(info)def enqueue_shipping_confirmation_email(logisticsTxnId, orderList):# Calling helper service on productionorder = orderList[0]helperClient = HelperClient(host_key = "helper_service_server_host_prod").get_client()emailSubject = 'Shipping Details for Master Order ID: ' + logisticsTxnIdemailBody = get_shipping_confirmation_email_body(logisticsTxnId, orderList)helperClient.saveUserEmailForSending([order.customer_email], SaholicHelpEmailId, emailSubject, emailBody, logisticsTxnId, 'ShippingConfirmation', [], [], order.source)logistics_providers = {1: {'name': 'BlueDart', 'phone': '011-66111234'}, 6: {'name': 'RedExpress', 'phone': '8373915813'}, 3: {'name': 'Delhivery', 'phone' : '0124- 4212200'}, 7: {'name': 'FedEx', 'phone' : '0120-4354176'}}provider_name = logistics_providers[order.logistics_provider_id]['name']if order.source == OrderSource.WEBSITE :send_transaction_sms(order.customer_id, order.customer_mobilenumber, "Dear Customer, We have shipped your order: " + logisticsTxnId + " through "+provider_name + " AWB No. " + order.airwaybill_no, SmsType.TRANSACTIONAL, True)def get_order_distribution_by_status(start_date, end_date):query = session.query(Order.status, func.count(Order.id)).group_by(Order.status)query = query.filter(Order.created_timestamp >= start_date)query = query.filter(Order.created_timestamp <= end_date)return query.all()def get_order_ids_for_status(status, start_datetime, end_datetime):query = Order.query.filter(Order.status == status)query = query.filter(Order.created_timestamp >= start_datetime)query = query.filter(Order.created_timestamp <= end_datetime)return query.all()def update_orders_as_paid_to_vendor(order_id):paid_order = Order.get_by(id = order_id)if paid_order.originalOrderId is None:paid_order.vendor_paid = Truesession.commit()for order in Order.query.filter(Order.originalOrderId == order_id).all():order.vendor_paid = Truesession.commit()else:original_order_id = paid_order.originalOrderIdfor order in Order.query.filter(Order.originalOrderId == original_order_id).all():order.vendor_paid = Truesession.commit()original_order = Order.get_by(id = original_order_id)if original_order: original_order.vendor_paid = Truesession.commit()def update_COD_agent(agentEmailId, orderId):order = Order.get_by(id=orderId)if not order:raise TransactionServiceException(101, "No order found for the given order id" + str(orderId))agent = CodVerificationAgent()agent.orderId = orderIdagent.verificationAgent = agentEmailIdsession.commit()def update_order_only_as_paid_to_vendor(order_id):paid_order = Order.get_by(id = order_id)if paid_order is None:raise TransactionServiceException(116, "No order found for the given order id")paid_order.vendor_paid = Truesession.commit()def get_refunded_orders_marked_paid():orderStatusGroup = OrderStatusGroups()return Order.query.filter(Order.vendor_paid == 1).filter(Order.status.in_(orderStatusGroup.refundedOrders)).all()def get_all_verification_agents(minOrderId, maxOrderId):return CodVerificationAgent.query.filter(CodVerificationAgent.orderId >= minOrderId).filter(CodVerificationAgent.orderId <= maxOrderId).all()def get_all_attributes_for_order_id(orderId):return Attribute.query.filter(Attribute.orderId == orderId).all()def set_order_attribute_for_transaction(transactionId, t_attribute):for order in Order.query.filter_by(transaction_id = transactionId).all():attribute = Attribute()attribute.orderId = order.idattribute.name = t_attribute.nameattribute.value = t_attribute.valuesession.commit()def accept_order_for_item(itemId, quantity, fulfilmentWarehouseId, billingWarehouseId):inventoryClient = InventoryClient().get_client()inventory = inventoryClient.getItemInventoryByItemId(itemId)orders = Order.query.filter(Order.fulfilmentWarehouseId != fulfilmentWarehouseId).filter(Order.warehouse_id == billingWarehouseId).filter(Order.status.in_(tuple([OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.COD_VERIFICATION_PENDING, OrderStatus.ACCEPTED, OrderStatus.INVENTORY_LOW, OrderStatus.LOW_INV_PO_RAISED, OrderStatus.LOW_INV_REVERSAL_IN_PROCESS]))).order_by(Order.expected_shipping_time).all()for order in orders:if order.source ==6:continuelineitem = order.lineitems[0]if lineitem.item_id == itemId and lineitem.quantity <= quantity:warehouse = inventoryClient.getWarehouse(order.fulfilmentWarehouseId)if not warehouse.billingWarehouseId and warehouse.warehouseType == WarehouseType.THIRD_PARTY:if (inventory.availability[fulfilmentWarehouseId] >= inventory.reserved[fulfilmentWarehouseId] + lineitem.quantity) and inventory.availability[order.fulfilmentWarehouseId] < inventory.reserved[order.fulfilmentWarehouseId]:inventoryClient.reduceReservationCount(itemId, order.fulfilmentWarehouseId, sourceId, order.id, lineitem.quantity)inventoryClient.reserveItemInWarehouse(itemId, fulfilmentWarehouseId, sourceId, order.id, to_java_date(order.created_timestamp), to_java_date(order.promised_shipping_time), lineitem.quantity)order.fulfilmentWarehouseId = fulfilmentWarehouseIdquantity -= lineitem.quantitysession.commit()if not quantity:breakdef get_recharge_order(rechargeOrderId):return RechargeOrder.get_by(id = rechargeOrderId)def get_recharge_orders(userId, offset=None, limit=None):if offset > 0 and limit > 0:return RechargeOrder.query.filter_by(userId = userId).order_by(RechargeOrder.id.desc()).offset(offset).limit(limit).all()return RechargeOrder.query.filter_by(userId = userId).all()def update_recharge_order_status(rechargeOrderId, rechargeOrderStatus):recharge_order = get_recharge_order(rechargeOrderId)if rechargeOrderStatus == RechargeOrderStatus.PAYMENT_FAILED:recharge_order.status = RechargeOrderStatus.PAYMENT_FAILEDsession.commit()return Trueif rechargeOrderStatus == RechargeOrderStatus.RECHARGE_FAILED:if recharge_order.status == RechargeOrderStatus.RECHARGE_FAILED:return Truerecharge_order.status = RechargeOrderStatus.RECHARGE_FAILEDrecharge_order.responseTimestamp = datetime.datetime.now()session.commit()#update_amount_in_wallet(recharge_order.userId, recharge_order.walletAmount, recharge_order.id, 1)reverse_money_to_wallet(recharge_order.userId, recharge_order.walletAmount, recharge_order.id, WalletReferenceType.RECHARGE)#update_amount_in_wallet(recharge_order.userId, recharge_order.totalAmount - recharge_order.walletAmount - recharge_order.couponAmount, recharge_order.id, 0)add_amount_in_wallet(recharge_order.userId, recharge_order.totalAmount - recharge_order.walletAmount - recharge_order.couponAmount, recharge_order.id,WalletReferenceType.RECHARGE, False, "Recharge failed, Refunded", commit_session=True)enqueue_recharge_info_email(recharge_order)return Trueif rechargeOrderStatus == RechargeOrderStatus.RECHARGE_SUCCESSFUL:if recharge_order.status == RechargeOrderStatus.RECHARGE_SUCCESSFUL:return Truerecharge_order.status = RechargeOrderStatus.RECHARGE_SUCCESSFULrecharge_order.responseTimestamp = datetime.datetime.now()recharge_order.invoiceNumber = get_next_invoice_number(OrderType.RECHARGE)#Add commissions as wellpendingRechargeCommissions = PendingRechargeCommissions.query.filter(PendingRechargeCommissions.user_id == recharge_order.userId).first()if not pendingRechargeCommissions:pendingRechargeCommissions = PendingRechargeCommissions()pendingRechargeCommissions.user_id = recharge_order.userIdpendingRechargeCommissions.approvedAmountInPaise = 0pendingRechargeCommissions.lastUpdated = recharge_order.responseTimestampif isinstance(recharge_order, MobileRechargeOrder):commissions = mobileRechargeCommissionif isinstance(recharge_order, DTHRechargeOrder):commissions = dthRechargeCommissionpendingRechargeCommissions.approvedAmountInPaise += int(round(recharge_order.totalAmount*commissions))#Add amount to wallet if PendingRechargeCommissions are greater than Rs. 10if pendingRechargeCommissions.approvedAmountInPaise > 1000:commission_amount = int(pendingRechargeCommissions.approvedAmountInPaise/100)pendingRechargeCommissions.approvedAmountInPaise = pendingRechargeCommissions.approvedAmountInPaise%100add_amount_in_wallet(recharge_order.userId, commission_amount, str(datetime.datetime.now()), WalletReferenceType.RECHARGE_COMMISSIONS, True, "Cashback for Recharge commissions", False)session.commit()gvs = allocate_gift_voucher(recharge_order)enqueue_recharge_info_email(recharge_order, gvs)return Trueif rechargeOrderStatus == RechargeOrderStatus.RECHARGE_FAILED_REFUNDED:if recharge_order.status == RechargeOrderStatus.RECHARGE_FAILED_REFUNDED:return Truerecharge_order.status = RechargeOrderStatus.RECHARGE_FAILED_REFUNDEDrecharge_order.responseTimestamp = datetime.datetime.now()session.commit()#update_amount_in_wallet(recharge_order.userId, recharge_order.walletAmount, recharge_order.id, 1)#update_amount_in_wallet(recharge_order.userId, recharge_order.totalAmount - recharge_order.walletAmount - recharge_order.couponAmount, recharge_order.id, 0)reverse_money_to_wallet(recharge_order.userId, recharge_order.walletAmount, recharge_order.id, WalletReferenceType.RECHARGE)add_amount_in_wallet(recharge_order.userId, recharge_order.totalAmount - recharge_order.walletAmount - recharge_order.couponAmount, recharge_order.id,WalletReferenceType.RECHARGE, False, "Recharge failed, Refunded", commit_session=True)enqueue_recharge_info_email(recharge_order)return Trueif rechargeOrderStatus == RechargeOrderStatus.PAYMENT_SUCCESSFUL:gvs = {}recharge_order.status = RechargeOrderStatus.PAYMENT_SUCCESSFULsession.commit()if recharge_order.walletAmount > 0:wallet = get_user_wallet(recharge_order.userId)if wallet and wallet.amount >= recharge_order.walletAmount:#update_amount_in_wallet(recharge_order.userId, -recharge_order.walletAmount, recharge_order.id, 1)consume_wallet(recharge_order.userId, recharge_order.walletAmount, recharge_order.id, WalletReferenceType.RECHARGE, "Against recharge")else:## User is trying to play smart. Let us first mark his recharge failed and then credit payment amount to his wallet.recharge_order.status = RechargeOrderStatus.RECHARGE_FAILEDrecharge_order.responseTimestamp = datetime.datetime.now()session.commit()#update_amount_in_wallet(recharge_order.userId, recharge_order.totalAmount - recharge_order.walletAmount - recharge_order.couponAmount, recharge_order.id, 0)add_amount_in_wallet(recharge_order.userId, recharge_order.totalAmount - recharge_order.walletAmount - recharge_order.couponAmount, recharge_order.id,WalletReferenceType.RECHARGE, False, "Refunded against failed recharge", commit_session=True)raise TransactionServiceException(103, 'Wallet amount has already been used')try:if activate_recharge_txn(recharge_order):recharge_order.invoiceNumber = get_next_invoice_number(OrderType.RECHARGE)session.commit()gvs = allocate_gift_voucher(recharge_order)return Trueelse:#update_amount_in_wallet(recharge_order.userId, recharge_order.walletAmount, recharge_order.id, 1)#update_amount_in_wallet(recharge_order.userId, recharge_order.totalAmount - recharge_order.walletAmount - recharge_order.couponAmount, recharge_order.id, 0)reverse_money_to_wallet(recharge_order.userId, recharge_order.walletAmount, recharge_order.id, WalletReferenceType.RECHARGE)add_amount_in_wallet(recharge_order.userId, recharge_order.totalAmount - recharge_order.walletAmount - recharge_order.couponAmount, recharge_order.id,WalletReferenceType.RECHARGE, False, commit_session=True)session.commit()return Falseexcept:if isinstance(recharge_order, MobileRechargeOrder):if recharge_order.mobileOperatorId not in (getSyncOperatorsForRecharge()):print "I Am returned from here", recharge_order.walletAmountreturn Trueif isinstance(recharge_order, DTHRechargeOrder):if recharge_order.dthOperatorId not in (getSyncOperatorsForRecharge()):return Truetransaction_requiring_extra_processing = TransactionRequiringExtraProcessing()transaction_requiring_extra_processing.category = 'RECHARGE_UNKNOWN'transaction_requiring_extra_processing.transaction_id = recharge_order.transaction_idsession.commit()return Falsefinally:enqueue_recharge_info_email(recharge_order, gvs)def disburse_recharge_commissions():pass#get the minimum amount that can be disburseddef allocate_gift_voucher(recharge_order):totalAmount = recharge_order.totalAmountgvs = {}return gvsif totalAmount >= 100:totalAmount=500 if totalAmount >= 500 else totalAmounttry:pc = PromotionClient().get_client()enddate = datetime.datetime.now() + datetime.timedelta(days=45)while totalAmount > 0:gvAmount = totalAmount if totalAmount <= 250 else 250totalAmount = totalAmount - gvAmountgv = pc.createCoupon(26,CouponCategory.CUSTOMER_SATISFACTION , to_java_date(enddate), recharge_order.userEmailId, gvAmount, False, 1, None)gvs[gv] = gvAmountexcept:print "Not able to create gift voucher for user " + recharge_order.userEmailIdreturn gvsdef activate_recharge_txn(recharge_order):if isinstance(recharge_order, MobileRechargeOrder):rechargeType = 'MTP'deviceNumber = recharge_order.mobileNumberstrProviderCode = get_provider_code(recharge_order.mobileOperatorId)plan = recharge_order.rechargePlanif recharge_order.mobileOperatorId not in (getSyncOperatorsForRecharge()):__activate_recharge_txn_asynchronously(recharge_order,rechargeType,deviceNumber,strProviderCode,plan)if isinstance(recharge_order, DTHRechargeOrder):rechargeType = 'RCH'deviceNumber = recharge_order.dthAccountNumberstrProviderCode = get_provider_code(recharge_order.dthOperatorId)plan = ''if recharge_order.dthOperatorId not in (getSyncOperatorsForRecharge()):__activate_recharge_txn_asynchronously(recharge_order,rechargeType,deviceNumber,strProviderCode,plan)retStatus, retCode, spiceTID, description, aggTID, providerTID = RechargeService.rechargeDevice(recharge_order.id, rechargeType, strProviderCode, deviceNumber, recharge_order.totalAmount, plan, '' ,RechargeMode._NAMES_TO_VALUES.get('SYNC'))recharge_order.spiceTID = spiceTIDrecharge_order.responseTimestamp = datetime.datetime.now()recharge_order.description = descriptionsession.commit()if retCode == '00' and retStatus == 'S':recharge_order.status = RechargeOrderStatus.RECHARGE_SUCCESSFULsession.commit()if recharge_order.couponAmount > 0 :couponCode = recharge_order.couponCodeif couponCode :try:promotionServiceClient = PromotionClient()promotionServiceClient.get_client().trackCouponUsage(couponCode, recharge_order.id, recharge_order.userId)except Exception as e:print 'Unable to track the usage of coupon - ' + recharge_order.couponCode + ' and spiceTID - ' + str(spiceTID)print ereturn Trueelif retCode in ('STO', 'US', 'UP', 'STP') and retStatus == 'S':if recharge_order.couponAmount > 0 :couponCode = recharge_order.couponCodeif couponCode :try:promotionServiceClient = PromotionClient()promotionServiceClient.get_client().trackCouponUsage(couponCode, recharge_order.id, recharge_order.userId)except Exception as e:print 'Unable to track the usage of coupon - ' + recharge_order.couponCode + ' and spiceTID - ' + str(spiceTID)print eraise TransactionServiceException(111, "No response from operator within specified time")else:recharge_order.status = RechargeOrderStatus.RECHARGE_FAILEDif retCode in ('SVAI', 'SVIA', 'AI', 'IA', 'EAI', 'SVEAI'):recharge_order.description = "Invalid Amount"elif retCode in ('ECL', 'SVECL', 'SCL'):recharge_order.description = "Customer Exceeded Daily Limit"elif retCode in ('CI', 'ECI', 'ESP', 'SVCI', 'SVECI', 'SVESP', 'SV_ECI', 'SV ECI'):recharge_order.description = "Invalid Device Number"session.commit()return Falsedef __activate_recharge_txn_asynchronously(recharge_order, rechargeType, deviceNumber, strProviderCode, plan):if recharge_order.couponAmount > 0 :couponCode = recharge_order.couponCodeif couponCode :try:promotionServiceClient = PromotionClient()promotionServiceClient.get_client().trackCouponUsage(couponCode, recharge_order.id, recharge_order.userId, recharge_order.couponAmount, True)except Exception as e:print 'Unable to track the usage of coupon - ' + recharge_order.couponCode + ' and rechargeOrderId - ' + str(recharge_order.id)raise(TransactionServiceException(111, "Unable to track coupon usage"))retStatus, retCode, spiceTID, description, aggTID, providerTID = RechargeService.rechargeDevice(recharge_order.id, rechargeType, strProviderCode, deviceNumber, recharge_order.totalAmount, plan, '' ,RechargeMode._NAMES_TO_VALUES.get('ASYNC'))recharge_order.spiceTID = spiceTIDrecharge_order.responseTimestamp = datetime.datetime.now()recharge_order.status = RechargeOrderStatus.RECHARGE_UNKNOWNrecharge_order.description = 'Recharge In Process'session.commit()raise(TransactionServiceException(111, "Explicitly raising exception, will try to fetch final status"))def get_user_wallet(userId):wallet = UserWallet.get_by(userId = userId)if not wallet:wallet = UserWallet()wallet.amount = 0wallet.userId = userIdwallet.refundable_amount = 0return walletdef get_user_wallet_history(userId, offset=0, limit=50):wallet = get_user_wallet(userId)if wallet.id:return UserWalletHistory.query.filter_by(wallet = wallet).order_by(desc(UserWalletHistory.id)).offset(offset).limit(limit).all()else:return []def get_provider(providerId):return ServiceProvider.query.filter_by(id = providerId).one()def get_provider_code(providerId):return ServiceProvider.query.filter_by(id = providerId).one().codedef get_provider_by_code(providerCode):return ServiceProvider.query.filter_by(code = providerCode).one()def get_service_providers(recharge_type, only_active):query = ServiceProvider.query.filter_by(type = recharge_type)if only_active:query = query.filter_by(status = only_active)providers = query.all()serviceProviders = {}for provider in providers:serviceProviders[provider.id] = provider.namereturn serviceProvidersdef get_service_provider_for_device(rechargeType, deviceNumber):#FIXME : This method does not take care of MNP cases.if rechargeType == RechargeType.MOBILE:serviceType = 'MTP'if rechargeType == RechargeType.DTH:serviceType = 'RCH'provider = Nonetry:series = OperatorSeries.get_by(series = int(deviceNumber))if series:providerId = series.operatorIdtc = TelecomCircle.get_by(id = series.circleId)operatorCircle = tc.codeprovider = get_provider(providerId)else:l = len(deviceNumber)if l < 10:deviceNumber = deviceNumber + "0" * (10-l)providerCode, operatorCircle = RechargeService.checkServiceProviderApi(serviceType, deviceNumber)if providerCode == 'SNS' or providerCode == '':providerId = 0else:provider = get_provider_by_code(providerCode)providerId = provider.idexcept:providerId = -1operatorCircle = ""deviceNumberInfo = DeviceNumberInfo()deviceNumberInfo.circleCode = operatorCircledeviceNumberInfo.operatorId = providerIdif provider:deviceNumberInfo.operatorName = provider.namereturn deviceNumberInfodef validate_recharge(rechargeType, deviceNumber, userSelectedProviderId, clientAddress):addressComponents = clientAddress.split('.')n = 3addressNumber = 0for addressComponent in addressComponents :addressNumber = addressNumber + (int(addressComponent) * pow(256, n))n = n-1matchingRow = BlockedIpRange.query.filter(BlockedIpRange.start <= addressNumber).filter(BlockedIpRange.end >= addressNumber).first()#if a match is found then check if date has expired.if matchingRow :#if expiredOn is None that means this range is permanently blocked.if matchingRow.expiredOn is None:deniedIpAddress = DeniedIpAddress()deniedIpAddress.ip = clientAddressdeniedIpAddress.deniedOn = datetime.datetime.now()deniedIpAddress.deviceNumber = deviceNumberdeniedIpAddress.rechargeType = rechargeTypesession.commit()return "Oops! There seems to be a problem. Please try after some time."else :#if expired is not None and the blockage is still not expired then block the ip.if matchingRow.expiredOn > datetime.datetime.now():deniedIpAddress = DeniedIpAddress()deniedIpAddress.ip = clientAddressdeniedIpAddress.deniedOn = datetime.datetime.now()deniedIpAddress.deviceNumber = deviceNumberdeniedIpAddress.rechargeType = rechargeTypesession.commit()return "Oops! There seems to be a problem. Please try after some time."#FIXME : MNP cases are not being handled.deviceNumberInfo = get_service_provider_for_device(rechargeType, deviceNumber)if deviceNumberInfo.operatorId == -1:return "Oops! There seems to be a problem. Please try after some time."circle = TelecomCircle.query.filter_by(code = deviceNumberInfo.circleCode).first()if circle:serviceAvailability = ServiceAvailability.query.filter_by(circleId = circle.id).filter_by(operatorId = userSelectedProviderId).first()if serviceAvailability.permIsServiceAvailable == False or serviceAvailability.tempIsServiceAvailable == False :if deviceNumberInfo.operatorName :if serviceAvailability.permIsServiceAvailable == False:return "We currently do not provide service for " + deviceNumberInfo.operatorName + " in " + circle.name + ". We regret the inconvenience."else :return "We are facing technical issues with " + deviceNumberInfo.operatorName + " in " + circle.name + " currently. Please try later."else :if serviceAvailability.permIsServiceAvailable == False:return "We currently do not provide service for this operator in " + circle.name + ". We regret the inconvenience."else:return "We are facing technical issues with this operator in " + circle.name + " currently. Please try later."totalSuccessfulRechargeAmount = get_previous_transactions(clientAddress)if totalSuccessfulRechargeAmount >= 3000 :return "You have exceeded your daily recharge limit. Please try after 24 hours."return "SUCCESS"def get_previous_transactions(clientAddress):limittime = datetime.datetime.now() - datetime.timedelta(hours=24)totalSuccessfulRechargeAmount = session.query(func.sum(RechargeOrder.totalAmount)).filter(RechargeOrder.status == 5).filter(RechargeOrder.ipAddress == clientAddress).filter(RechargeOrder.creationTimestamp > limittime).scalar()return totalSuccessfulRechargeAmountdef refund_to_wallet(userId, amount, reference, reference_type, description='Refunded to wallet', commit_session=False):"""Commit to be decided by caller"""if amount <= 0 or WalletReferenceType._VALUES_TO_NAMES.get(reference_type) is None:return Falseall_entries = UserWalletHistory.query.filter_by(reference = reference).filter_by(reference_type = WalletReferenceType._VALUES_TO_NAMES.get(reference_type)).all()creditable_amount_for_reference = 0refundable_amount_for_reference = 0for history in all_entries:creditable_amount_for_reference -= history.amountrefundable_amount_for_reference -= history.refundable_amount#Refundable amount for reference should be greater than the refund amountif creditable_amount_for_reference < amount:print 'Cant be credited back to wallet as most of it has been already credited'return Falsewallet = get_user_wallet(userId)wallet.amount = wallet.amount + amountrefundable_amount = 0if creditable_amount_for_reference - refundable_amount_for_reference < amount:refundable_amount = amount - (creditable_amount_for_reference - refundable_amount_for_reference)wallet.refundable_amount = wallet.refundable_amount + refundable_amounthistory = UserWalletHistory()history.amount = amounthistory.refundable_amount = refundable_amounthistory.reference = referencehistory.reference_type = WalletReferenceType._VALUES_TO_NAMES.get(reference_type)history.wallet = wallethistory.timestamp = datetime.datetime.now()history.description = descriptionif commit_session:session.commit()def add_amount_in_wallet(userId, amount, reference, reference_type, isPromotional, description=None, commit_session=False):"""Commit to be decided by caller"""if not amount > 0 or WalletReferenceType._VALUES_TO_NAMES.get(reference_type) is None:returnwallet = get_user_wallet(userId)wallet.amount = wallet.amount + amounthistory = UserWalletHistory()history.refundable_amount = 0if not isPromotional:wallet.refundable_amount = wallet.refundable_amount + amounthistory.refundable_amount = amounthistory.amount = amounthistory.reference = referencehistory.reference_type = WalletReferenceType._VALUES_TO_NAMES.get(reference_type)history.wallet = wallethistory.description = descriptionhistory.timestamp = datetime.datetime.now()if commit_session:session.commit()def consume_wallet(userId, amount, reference, reference_type, description):if amount <= 0 or WalletReferenceType._VALUES_TO_NAMES.get(reference_type) is None:returnwallet = get_user_wallet(userId)refundable_amount = wallet.refundable_amountpromotional_amount = wallet.amount - wallet.refundable_amountrefundable_amount_used = 0if promotional_amount < amount:refundable_amount = refundable_amount - (amount - promotional_amount)refundable_amount_used = amount - promotional_amountpromotional_amount = 0else:promotional_amount = promotional_amount - amountwallet.amount = promotional_amount + refundable_amountwallet.refundable_amount = refundable_amounthistory = UserWalletHistory()history.amount = -amounthistory.refundable_amount = -refundable_amount_usedhistory.reference = referencehistory.reference_type = WalletReferenceType._VALUES_TO_NAMES.get(reference_type)history.wallet = wallethistory.description = descriptionhistory.timestamp = datetime.datetime.now()session.commit()def refund_amount_from_wallet(userId, amount, reference, reference_type, description="Refunded to customer"):if amount <= 0 or WalletReferenceType._VALUES_TO_NAMES.get(reference_type) is None:returnwallet = get_user_wallet(userId)wallet.amount = wallet.amount - amountwallet.refundable_amount = wallet.refundable_amount - amountif wallet.refundable_amount < 0:returnhistory = UserWalletHistory()history.amount = -amounthistory.refundable_amount = -amounthistory.reference = referencehistory.reference_type = WalletReferenceType._VALUES_TO_NAMES.get(reference_type)history.wallet = wallethistory.description = descriptionhistory.timestamp = datetime.datetime.now()session.commit()def reverse_money_to_wallet(userId, amount, reference, reference_type):"""To only reverse wallet payments, check add_amount_in_wallet to add new amount"""if amount <= 0 or WalletReferenceType._VALUES_TO_NAMES.get(reference_type) is None:returnprevious_debit_history = Noneif reference_type==WalletReferenceType.RECHARGE:previous_debit_history = UserWalletHistory.query.filter_by(reference = reference).filter_by(reference_type = WalletReferenceType._VALUES_TO_NAMES.get(reference_type)).filter_by(amount = -amount).order_by(UserWalletHistory.id.desc()).first()if previous_debit_history is None:print 'No amount was debited from wallet for recharge Id : ' + str(reference)returnelif reference_type==WalletReferenceType.PURCHASE:previous_debit_history = UserWalletHistory.query.filter_by(reference = reference).filter_by(reference_type = WalletReferenceType._VALUES_TO_NAMES.get(reference_type)).filter_by(amount = -amount).order_by(UserWalletHistory.id.desc()).first()if previous_debit_history is None:print 'No amount was debited from wallet for purchase : ' + str(reference)returnelse:print "Reference is not valid"returnwallet = get_user_wallet(userId)wallet.amount = wallet.amount + amountwallet.refundable_amount = wallet.refundable_amount -previous_debit_history.refundable_amounthistory = UserWalletHistory()history.amount = amounthistory.refundable_amount = -previous_debit_history.refundable_amounthistory.reference = referencehistory.reference_type = WalletReferenceType._VALUES_TO_NAMES.get(reference_type)history.wallet = wallethistory.timestamp = datetime.datetime.now()history.description = "Wallet amount reversed"session.commit()#def update_amount_in_wallet(userId, amount, orderId, updateType):# return# """# UpdateType 1 is for wallet amounts# and 0 is for payment amounts# """# if amount == 0:# return## history = None# if updateType == 1 and amount > 0 :# history = UserWalletHistory.query.filter_by(orderId = orderId).filter_by(amount = -amount).order_by(UserWalletHistory.id.desc()).first()# if history is None:# print 'No amount was debited from wallet for recharge Id : ' + str(orderId)# return## """# TODO check if successful payment available or Not# elif updateType == 0 :# baseorder = BaseOrder.query.filter_by(id = orderId).first()# if baseorder :# try :# pc = PaymentClient().get_client()# payments = pc.getPaymentForRechargeTxnId(baseorder.transaction.id)# except Exception as e:# print e# return# for payment in payments :# if payment.status == 2 :# break# else :# return# """# wallet = get_user_wallet(userId)# wallet.amount = wallet.amount + amount## history = UserWalletHistory()# history.amount = amount# history.orderId = orderId# history.wallet = wallet# history.timestamp = datetime.datetime.now()# session.commit()def get_recharge_orders_for_device(deviceNumber):orders = MobileRechargeOrder.query.filter_by(mobileNumber = deviceNumber).all()if orders is None:orders = DTHRechargeOrder.query.filter_by(dthAccountNumber = deviceNumber).all()return ordersdef get_recharge_orders_for_status(status):if status == -1:orders = RechargeOrder.query.order_by(desc(RechargeOrder.id)).all()else:orders = RechargeOrder.query.order_by(desc(RechargeOrder.id)).filter_by(status = status).all()return ordersdef get_recharge_statistics():rs = RechargeStatistics()statusCounts = {}operatorCounts = {}currentOrders = {}amounts = {}sorders = session.query(RechargeOrder.status, func.count(RechargeOrder.status)).group_by(RechargeOrder.status).all()for sorder in sorders:statusCounts[sorder[0]] = sorder[1]oorders = session.query(MobileRechargeOrder.mobileOperatorId, func.count(MobileRechargeOrder.mobileOperatorId)).group_by(MobileRechargeOrder.mobileOperatorId).all()for oorder in oorders:operatorCounts[oorder[0]] = oorder[1]oorders = session.query(DTHRechargeOrder.dthOperatorId, func.count(DTHRechargeOrder.dthOperatorId)).group_by(DTHRechargeOrder.dthOperatorId).all()for oorder in oorders:operatorCounts[oorder[0]] = oorder[1]forders = RechargeOrder.query.order_by(desc(RechargeOrder.id)).filter_by(status = RechargeOrderStatus.RECHARGE_FAILED).limit(20).all()currentOrders[RechargeOrderStatus._VALUES_TO_NAMES.get(RechargeOrderStatus.RECHARGE_FAILED)] = [order.to_thrift_object() for order in forders]sorders = RechargeOrder.query.order_by(desc(RechargeOrder.id)).filter_by(status = RechargeOrderStatus.RECHARGE_SUCCESSFUL).limit(20).all()currentOrders[RechargeOrderStatus._VALUES_TO_NAMES.get(RechargeOrderStatus.RECHARGE_SUCCESSFUL)] = [order.to_thrift_object() for order in sorders]porders = RechargeOrder.query.order_by(desc(RechargeOrder.id)).filter_by(status = RechargeOrderStatus.PAYMENT_SUCCESSFUL).limit(20).all()currentOrders[RechargeOrderStatus._VALUES_TO_NAMES.get(RechargeOrderStatus.PAYMENT_SUCCESSFUL)] = [order.to_thrift_object() for order in porders]rorders = RechargeOrder.query.order_by(desc(RechargeOrder.id)).filter_by(status = RechargeOrderStatus.RECHARGE_FAILED_REFUNDED).limit(20).all()currentOrders[RechargeOrderStatus._VALUES_TO_NAMES.get(RechargeOrderStatus.RECHARGE_FAILED_REFUNDED)] = [order.to_thrift_object() for order in rorders]twa = session.query(func.sum(UserWallet.amount)).one()tra = session.query(func.sum(RechargeOrder.totalAmount)).filter(RechargeOrder.status == RechargeOrderStatus.RECHARGE_SUCCESSFUL).one()gwa = session.query(func.sum(UserWalletHistory.amount)).filter(UserWalletHistory.orderId > 100000).one()dit2 = session.query(func.sum(WalletHistoryForCompany.amount)).filter(WalletHistoryForCompany.walletId == 2).filter(WalletHistoryForCompany.amount >= 100000).one()tpa = session.query(func.sum(RechargeOrder.totalAmount-RechargeOrder.walletAmount-RechargeOrder.couponAmount)).filter(RechargeOrder.status.in_((RechargeOrderStatus.RECHARGE_SUCCESSFUL, RechargeOrderStatus.RECHARGE_FAILED, RechargeOrderStatus.PAYMENT_SUCCESSFUL, RechargeOrderStatus.RECHARGE_FAILED_REFUNDED))).one()tda = session.query(func.sum(RechargeOrder.couponAmount)).filter(RechargeOrder.status == RechargeOrderStatus.RECHARGE_SUCCESSFUL).one()balance = RechargeService.getBalance()amounts['(a) Total Payment Amount'] = tpa[0]amounts['(b) Gift Wallet Amount'] = gwa[0]amounts['(c) Total Wallet Amount'] = twa[0]amounts['(d) Total Recharge Amount'] = tra[0]amounts['(e) Discount Balance'] = tda[0]amounts['Saholic Mismatch = (a+b+f-c-d)'] = tpa[0] + gwa[0] + tda[0] - tra[0] - twa[0] + 57607'''if amounts['SpiceDeck Mismatch = (d-e)'] != -739:mail(mail_user, mail_password, ['rajneesh.arora@shop2020.in', 'rajveer.singh@shop2020.in', 'kshitij.sood@shop2020.in'], "SpiceDeck Account mismatch of amount " + str(amounts['SpiceDeck Mismatch = (d-e)']), "", [], [], [])if amounts['Saholic Mismatch = (a+b-c-d)'] != -1919:mail(mail_user, mail_password, ['rajneesh.arora@shop2020.in', 'rajveer.singh@shop2020.in', 'kshitij.sood@shop2020.in'], "Saholic Recharge Account mismatch of amount " + str(amounts['Saholic Mismatch = (a+b-c-d)']), "", [], [], [])'''rs.statusCounts = statusCountsrs.operatorCounts = operatorCountsrs.currentOrders = currentOrdersrs.amounts = amountsreturn rsdef get_plans_for_operator(operator_id):return RechargePlan.query.filter_by(operatorId = operator_id).all()def get_recharge_orders_for_transaction(txId):return RechargeOrder.query.filter_by(transaction_id = txId).first()def enqueue_recharge_info_email(recharge_order, gvs={}):status = ""message = ""html_header = """<html><body><div><p>Hello $email,<br /><br />Thanks for placing recharge order with us. Following are the details of your recharge order:</p><div>Order Id : $order_id <br/>Order Date : $order_date <br/>Order Amount : Rs. $order_amount <br/>Order Status : $order_status <br/>Device Number : $device_number <br/>Service Provider : $service_provider <br/></div><br />"""FailureReasonMap = {}FailureReasonMap["Invalid Amount"] = "the amount you tried seems to be invalid. Please try another amount."FailureReasonMap["Customer Exceeded Daily Limit"] = "you have exceeded daily recharge limit for this number. Please try after 12 hours."FailureReasonMap["Invalid Device Number"] = "it seems that your device number is not being recognized by selected operator. Please make sure the number you tried is correct."FailureReasonMapSms = {}FailureReasonMapSms["Invalid Amount"] = " invalid amount."FailureReasonMapSms["Customer Exceeded Daily Limit"] = " daily limit exceeded. Please try after 12Hrs."FailureReasonMapSms["Invalid Device Number"] = " invalid device number."failureReason = FailureReasonMap.get(recharge_order.description)failureReasonSms = FailureReasonMapSms.get(recharge_order.description)if failureReasonSms is None:failureReasonSms = " network failure."if failureReason is None:failureReason = "of network failure."if recharge_order.status == RechargeOrderStatus.RECHARGE_SUCCESSFUL:status = "Recharge Successful"message = ""if recharge_order.couponAmount > 0:message = message + "<b>You have used coupon " + recharge_order.couponCode + " and got discount of Rs. " + str(recharge_order.couponAmount) + ".</b>"elif recharge_order.status == RechargeOrderStatus.RECHARGE_FAILED:status = "Recharge Failed"message = """We could not process your recharge because $failureReason We have credited the amount to your recharge wallet. You can use wallet amount to recharge again. <a href="$source_url/static/recharge-faq">Learn More</a>"""elif recharge_order.status == RechargeOrderStatus.PAYMENT_SUCCESSFUL:status = "Recharge Under Process"message = """Your Payment was successful but due to some internal error with the operator's system we are not sure if the recharge was successful. In case your recharge is not processed, we will credit amount to your recharge wallet. You can use wallet amount to recharge again. <a href="$source_url/static/recharge-faq">Learn More</a>"""elif recharge_order.status == RechargeOrderStatus.RECHARGE_FAILED_REFUNDED:status = "Recharge Failed, Amount Refunded"message = """It seems operator could not process your recharge request. We are crediting the refund amount to your recharge wallet. You can use wallet amount to recharge again. <a href="$source_url/static/recharge-faq">Learn More</a>"""if len(gvs) > 0:message = message + '<br /> You have been awarded with following Gift Voucher(s). You can redeem Gift Voucher(s) to purchase any product for Rs. 5000 and above using credit/debit card and net banking. <a href="$source_url/static/giftvoucher-offer">More details</a>'message = message + " <br /> <b>Voucher Code            Amount</b>"for gv in gvs.keys():gvAmount = gvs.get(gv)message = message + " <br /> <b>" + gv + "           Rs. " + str(gvAmount) + "</b>"message = message + '<br /> In case of any problem, please <a href="$source_url/contact-us">contact us</a>'html_header = html_header + messagehtml_footer = """<p>Best Wishes,<br />$source_name Team</p></div></body></html>"""if isinstance(recharge_order, MobileRechargeOrder):deviceNumber = recharge_order.mobileNumberproviderName = get_provider(recharge_order.mobileOperatorId).nameif isinstance(recharge_order, DTHRechargeOrder):deviceNumber = recharge_order.dthAccountNumberproviderName = get_provider(recharge_order.dthOperatorId).namedisplay_order_id = recharge_order.idPrefix + str(recharge_order.id)email = recharge_order.userEmailIddt = datetime.datetime.strptime(str(recharge_order.creationTimestamp), "%Y-%m-%d %H:%M:%S")formated_order_date = dt.strftime("%A, %d. %B %Y %I:%M%p")email_header = Template(html_header).substitute(dict(order_id = display_order_id, order_date = formated_order_date, email = email, source_url = source_url, order_amount = recharge_order.totalAmount, order_status = status, device_number = deviceNumber, service_provider = providerName, failureReason = failureReason))email_footer = Template(html_footer).substitute(dict(source_url = source_url, source_name = source_name))if isinstance(recharge_order, MobileRechargeOrder):smsText = ""if status == "Recharge Failed" and recharge_order.description == "Invalid Device Number" :print "Do send Sms"'''try:helper_client = HelperClient().get_client()helper_client.saveUserEmailForSending([email], "", source_name + " - Recharge Order Details", email_header + email_footer, str(recharge_order.id), "RechargeInfo", [], [], 1)except Exception as e:print e'''elif status == "Recharge Failed" and recharge_order.description != "Invalid Device Number" :smsText = "Dear Customer, We could not process your recharge due to" + failureReasonSms + " We have credited the amount to your recharge wallet. You can use wallet amount to recharge again. "elif status == "Recharge Successful" :smsText = "Dear Customer, Thanks for recharging your mobile for Rs. "+ str(recharge_order.totalAmount) + " from SmartDukaan. Order Id is "+ display_order_id + ". Any Query? please call 8826894203"elif status == "Recharge Under Process" :smsText = "Dear Customer, Your Payment was successful but due to some internal error with the operator's system we are not sure if the recharge was successful. In case your recharge is not processed, we will credit amount to your recharge wallet."#Dear Customer, Your Payment was successful but due to some internal error with the operator's system we are not sure if the recharge was successful. In case your recharge is not processed, we will credit amount to your recharge wallet.elif status == "Recharge Failed, Amount Refunded" :smsText = "Dear Customer, It seems operator could not process your recharge request. We are crediting the refund amount to your recharge wallet. You can use wallet amount to recharge again."if smsText is not None and len(smsText)>0 and recharge_order.status!=RechargeOrderStatus.RECHARGE_UNKNOWN:try:send_transaction_sms(recharge_order.userId, deviceNumber, smsText, SmsType.TRANSACTIONAL, False)except Exception as e:print epassif recharge_order.status == RechargeOrderStatus.RECHARGE_UNKNOWN:return Truetry:helper_client = HelperClient().get_client()helper_client.saveUserEmailForSending([email], SaholicHelpEmailId, source_name + " - Recharge Order Details", email_header + email_footer, str(recharge_order.id), "RechargeInfo", [], [], 1)return Trueexcept Exception as e:print ereturn Falsedef get_recharge_denominations(operator_id, circleCode, denomination_type):circle_id = TelecomCircle.query.filter_by(code = circleCode).first().idreturn RechargeDenomination.query.filter_by(operatorId = operator_id).filter_by(circleId = circle_id).filter_by(denominationType = denomination_type).all()def update_availability_status(operatorId, circleId, isAvailable):serviceAvailability = ServiceAvailability.query.filter_by(circleId = circleId).filter_by(operatorId = operatorId).first()serviceAvailability.tempIsServiceAvailable = isAvailablesession.commit()def get_misc_charges(transactionId):retCharges = {}miscCharges = MiscCharges.get_by(transaction_id = transactionId)if miscCharges:retCharges[1] = miscCharges.chargeAmountreturn retChargesdef get_available_emi_schemes():t_emi_schemes = []emi_schemes = EmiScheme.query.filter(EmiScheme.minAmount < 9999999).all()if emi_schemes:t_emi_schemes = [to_t_emi_scheme(emi_scheme) for emi_scheme in emi_schemes]return t_emi_schemesdef refund_recharge_order(rechargeOrderId):try :rechargeOrder = RechargeOrder.query.filter_by(id = rechargeOrderId).first()wallet = UserWallet.query.filter_by(userId = rechargeOrder.userId).first()except:return FalsepaidAmount = rechargeOrder.totalAmount - rechargeOrder.walletAmount - rechargeOrder.couponAmountamountToRefund = 0status = Noneif (paidAmount <= wallet.refundable_amount) :amountToRefund = paidAmountstatus = RechargeOrderStatus.REFUNDEDelse :amountToRefund = wallet.refundable_amountstatus = RechargeOrderStatus.PARTIALLY_REFUNDED#update_amount_in_wallet(rechargeOrder.userId, -amountToRefund, rechargeOrderId, 1)refund_amount_from_wallet(rechargeOrder.userId, amountToRefund, rechargeOrderId, WalletReferenceType.RECHARGE)try:pc = PaymentClient().get_client()if pc.refundPayment(rechargeOrder.transaction_id, amountToRefund, True) :rechargeOrder.status = statusrechargeOrder.refundTimestamp = datetime.datetime.now()session.commit()return Trueelse :#update_amount_in_wallet(rechargeOrder.userId, amountToRefund, rechargeOrderId, 1)add_amount_in_wallet(rechargeOrder.userId, amountToRefund, rechargeOrderId, WalletReferenceType.RECHARGE, False, "Reversed while refunding to gateway", commit_session=True)except:#update_amount_in_wallet(rechargeOrder.userId, amountToRefund, rechargeOrderId, 1)add_amount_in_wallet(rechargeOrder.userId, amountToRefund, rechargeOrderId, WalletReferenceType.RECHARGE, False, "Reversed while refunding to gateway", commit_session=True)return Falsedef get_physical_orders(from_date, to_date):query = Order.query.filter(Order.created_timestamp >from_date).filter(Order.created_timestamp < to_date).filter(~Order.status.in_([0,1,6,11,14,15,18,19,31,34,28,53,54,55,56,20,21,77,79,78]))return query.all()def close_session():if session.is_active:print "session is active. closing it."session.close()def is_alive():try:session.query(Transaction.id).limit(1).one()return Trueexcept:return Falsedef get_document(docType, docSource):document = DocumentStore.get_by(docType = docType, docSource = docSource)if document:return document.documentelse:return bin(0)def retrieve_invoice(orderId, userId):order = get_order(orderId)if order.customer_id != userId:return bin(0)strOrderId = '0'*(10-len(str(orderId)))+str(orderId)filename = "/SaholicInvoices/" + strOrderId[0:2] + "/" + strOrderId[2:4] + "/" + strOrderId[4:6] + "/" + str(orderId) + ".pdf"file = open(filename, "rb")pdfFile = file.read()return pdfFiledef myFirstPage(canvas, doc):canvas.saveState()canvas.setTitle("Theft-Insurance-Policy")canvas.restoreState()def __generate_policy_doc(order, filename):PAGE_HEIGHT=defaultPageSize[1]; PAGE_WIDTH=defaultPageSize[0]styles = getSampleStyleSheet()styles.add(ParagraphStyle(name='left', leftIndent=12,fontSize=11), alias='li')styles.add(ParagraphStyle(name='bullet', bulletIndent=24, leftIndent=24), alias='bull')styles.add(ParagraphStyle(name='insurerName', alignment=TA_CENTER, fontName="Times-Bold", fontSize=16), alias='iN')styles.add(ParagraphStyle(name='insurerAdd', alignment=TA_CENTER, fontName="Helvetica",leading=15, fontSize=12), alias='iA')styles.add(ParagraphStyle(name='subHeading', alignment=TA_CENTER, fontName="Helvetica", fontSize=13), alias='sH')invoiceNumber = str(order.invoice_number)billing_timestamp = str(order.billing_timestamp.date())doc = SimpleDocTemplate(filename)Story = [Spacer(0, 0)]style = styles["Normal"]file_name = os.path.dirname(os.path.realpath(__file__)) + '/../resources/nia-logo.jpg'image = Image(file_name, width=100, height=100)Story.append(image)Story.append(Spacer(1,0.2*inch))text = ("""<u>The New India Assurance Company Limited</u>""")p = Paragraph(text, styles['insurerName'])Story.append(p)Story.append(Spacer(1,0.2*inch))text = ("""DO-IX, 35/1, Fortune Park, 1st Floor, Park Road, Tasker Town, Shivajinagar, Bangalore 560051""")p = Paragraph(text, styles['insurerAdd'])Story.append(p)Story.append(Spacer(1,0.3*inch))text = ("""MOBILE HAND SET INSURANCE – THEFT & BURGLARY RISKS ONLY""")p = Paragraph(text, styles['subHeading'])Story.append(p)Story.append(Spacer(1,1*inch))text = ("""<u><b>Subject Matter Of Insurance</b></u> : <i>New Mobile Handsets</i> alone and <i>Tablets with 'Voice Calls'</i> only.Sold 'online' by <b>Spice Online Retail Private Limited, New Delhi</b>, to its customers.""")p = Paragraph(text, style)Story.append(p)Story.append(Spacer(1,0.2*inch))text = ("""Insurer will indemnify the Insured in the event of Theft/Burglary of <i>Mobile Handsets</i>alone and <i>Tablets with 'Voice Calls'</i> only sold as per Invoice No. %sdated %s and insured with THE NEW INDIA ASSURANCE COMPANY LIMITED, BANGALORE, as per Policy No. 67020046142400000013,for a period of 12 months from the date and time of delivery of Mobile Handset to the customer.""" % (invoiceNumber, billing_timestamp))p = Paragraph(text, style)Story.append(p)Story.append(Spacer(1,0.2*inch))text = ("""<b>WARRANTY</b> - Warranted that the Mobile Handset sold during the Policy Period of 25/02/2015 to 24/02/2016are only covered irrespective of date of delivery to the customer""")p = Paragraph(text, style)Story.append(p)Story.append(Spacer(1,0.2*inch))text = ("<b>INSURER</b> -The New India Assurance company limited.")p = Paragraph(text, style)Story.append(p)Story.append(Spacer(1,0.2*inch))text = ("<b>INSURED</b> - Purchaser of the Mobile Handset OR his/her spouse or children. If the Purchaser is a ‘Company’, user is the duly authorised person.")p = Paragraph(text, style)Story.append(p)Story.append(Spacer(1,0.2*inch))text = ("<b>GEOGRAPHICAL LIMIT</b> – World-wide")p = Paragraph(text, style)Story.append(p)Story.append(Spacer(1,0.2*inch))text = ("<b>RISK COVERAGE</b> – Theft and/or burglary only")p = Paragraph(text, style)Story.append(p)Story.append(Spacer(1,0.4*inch))text = ("Terms and Conditions of Insurance:")p = Paragraph(text, styles["h2"])Story.append(p)Story.append(Spacer(1,0.1*inch))text = ("""Insurance Premium paid will not be refunded.""")p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')Story.append(p)Story.append(Spacer(1,0.1*inch))text = ("""Claims will be settled by UB Insurance Associates on behalf of The New India Assurance Co. Ltd.<br></br>Saholic.com will not be responsible for claim approval and disbursement.""")p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')Story.append(p)Story.append(Spacer(1,0.1*inch))text = ("""Insurance will be invalidated for returned products.""")p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')Story.append(p)Story.append(Spacer(1,0.3*inch))text = ("Exclusions:")p = Paragraph(text, styles["h2"])Story.append(p)Story.append(Spacer(1,0.1*inch))text = ("Insurer is not liable")p = Paragraph(text, styles["left"])Story.append(p)Story.append(Spacer(1,0.1*inch))text = ("If the handset is not connected to Mobile Service Provider Network")p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')Story.append(p)Story.append(Spacer(1,0.1*inch))text = ("Caused by incorrect storage, poor care and maintenance, careless use, negligence.")p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')Story.append(p)Story.append(Spacer(1,0.1*inch))text = ("Due to mysterious disappearance, forgotten or misplaced or Lost or if handset is left unattended at any point of time.")p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')Story.append(p)Story.append(Spacer(1,0.1*inch))text = ("Caused by war, war like operation, act of foreign enemy, civil war, rebellion, civil commotion, military usurped power, seizure, capture, confiscation, arrests, restrains and detainment by order of any Government or any other Authority.")p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')Story.append(p)Story.append(Spacer(1,0.1*inch))text = ("Caused whilst engaging in criminal acts.")p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')Story.append(p)Story.append(Spacer(1,0.1*inch))text = ("Caused by consequential loss or damage of whatsoever nature or any costs incurred in connection with claim under this policy, including postage, transit costs and reconnection cost.")p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')Story.append(p)Story.append(Spacer(1,0.1*inch))text = ("Loss of mobile handset due to theft from an unattended vehicle unless the vehicle is of fully enclosed saloon type having at time all the doors/windows and other opening securely locked and properly fastened.")p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')Story.append(p)Story.append(Spacer(1,0.1*inch))text = ("Loss of mobile handset due to theft from the building unless there is visible forcible entry/exit into/from the building.")p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')Story.append(p)Story.append(Spacer(1,0.1*inch))text = ("If the documents are found to be tampered; non-disclosure of material fact, fraud/misrepresentation.")p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')Story.append(p)Story.append(Spacer(1,0.1*inch))text = ("The policy is not transferable.")p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')Story.append(p)Story.append(Spacer(1,0.2*inch))text = ("Claim Procedure:")p = Paragraph(text, styles["h2"])Story.append(p)Story.append(Spacer(1,0.1*inch))text = ("""For Theft or Burglary of the handset immediate intimation to be givento the police within 48 hours of occurrence of incident and proper documents to be obtainedand inform the service provider within 48 hours about theft of handset in order to block the SIM services.""")p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')Story.append(p)Story.append(Spacer(1,0.1*inch))text = ("""To intimate Insurance Company about the loss of Mobile Handset within 48 hoursthrough Call Centre No.080-41258886 OR through e-mail <u>hkruniversal@gmail.com</u> OR throughwritten communication to <i>UB Insurance Associates (Insurance Consultants and Advisors), No.S-204-205, Suraj Plaza, 196/8, 25th Cross, 8th F Main, 3rd Block, Jayanagar, Bangalore – 560011, TEL - 08041258886; Mobile - +919448595917</i>.""")p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')Story.append(p)Story.append(Spacer(1,0.1*inch))text = ("""Claim documents can be downloaded through SPICE ONLINE RETAIL Website <u>http://www.saholic.com/claiminfo.html</u><br></br>To know or track your claim please contact Call Centre No. 022-49107910 of Universal Insurance brokers (UIB). """)p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')Story.append(p)Story.append(Spacer(1,0.1*inch))text = ("""All the completed claim documents to reach UB Insurance Associates (Insurance Consultants and Advisors), No.S-204-205, Suraj Plaza, 196/8, 25th Cross, 8th F Main, 3rd Block, Jayanagar, Bangalore – 560011, TEL - 08041258886; <b>within 21 days</b>.""")p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')Story.append(p)Story.append(Spacer(1,0.2*inch))text = ("""Claim proceeds will be credited to customer’s bank account.""")p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')Story.append(p)Story.append(Spacer(1,0.2*inch))text = ("Excess(Minimum Deduction):")p = Paragraph(text, styles["h2"])Story.append(p)Story.append(Spacer(1,0.1*inch))text = ("""The excess will be 5% of the value of each claim subject to a minimum of Rs.500/-""")p = Paragraph(text, styles["left"])Story.append(p)Story.append(Spacer(1,0.2*inch))text = ("Depreciation:")p = Paragraph(text, styles["h2"])Story.append(p)Story.append(Spacer(1,0.1*inch))text = ("For 0 – 60 days, 15%")p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')Story.append(p)Story.append(Spacer(1,0.1*inch))text = ("61-150 days, 30%")p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')Story.append(p)Story.append(Spacer(1,0.1*inch))text = ("151 – 365 days, 45%")p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')Story.append(p)Story.append(Spacer(1,0.4*inch))text = ("<i>Insurance is a subject matter of solicitation.</i>")p = Paragraph(text, style)Story.append(p)Story.append(Spacer(1,0.2*inch))doc.build(Story, onFirstPage=myFirstPage)def drawLine(Story, style):Story.append(Paragraph('-'*40, style))def generateHotSpotInvoice():##########TO BE PASSED TO THIS METHOD#############################################################################################################filename = "/home/anupam/test.pdf" ##########itemCode = "SPICEMI450WHT" ##########lotNumber = "12345678901234" ##########itemName = "Spice Stellar Craze Mi-450 White" ##########qty = 1 ##########unitPrice = 3099.50 ##########vat = 310.23 ##########billingTime = datetime.datetime.now() ##########invNum = "885182994" ##########counter = 1 ##########ourInvoiceNum = "209809" ##########customerId = "12345678909" ##########customerName = "ANUPAM PRATAP SINGH" ##########telNum = "" ###################################################################################PAGE_HEIGHT=defaultPageSize[1];styles = getSampleStyleSheet()styles.add(ParagraphStyle(name='prologue', alignment=TA_CENTER, fontName="Courier", rightIndent = 5, fontSize=10), alias='sH')styles.add(ParagraphStyle(name='text', alignment=TA_JUSTIFY, fontName="Courier", fontSize=10), alias='text')styles.add(ParagraphStyle(name='line', alignment=TA_CENTER, fontName="Courier", fontSize=10), alias='line')styles.add(ParagraphStyle(name='epilogue', alignment=TA_CENTER, fontName="Courier", leftIndent = 30, rightIndent=36, fontSize=10), alias='ep')Story = []prologueStyle = styles["prologue"]lineStyle = styles["line"]textStyle = styles["text"]epilogueStyle = styles["epilogue"]doc = BaseDocTemplate(filename,showBoundary=0)#Two Columnsframe1 = Frame(58, doc.bottomMargin, doc.width/2 + 25, doc.height + 7, id='col1')Story.append(Paragraph("""Spice Retail Limited<br></br>C/O,PIBCO LIMITED,Basement,Punjsons<br></br>2,Kalkaji Industrial Area,New Delhi<br></br>.<br></br>TIN NO. 07430284979<br></br>Service Tax No:AAACM0294PST001<br></br>D U P L I C A T E<br></br>I N V O I C E<br></br>""", prologueStyle))drawLine(Story, lineStyle)Story.append(Paragraph('{0:7s}{1:>11s}{2: %d/%m/%Y %H:%M:%S}'.format("INV NO:", invNum, billingTime).replace(" ", " "), textStyle))Story.append(Paragraph("{0:8s}{1:>5d}{2:>11s}{3:>11s}".format('COUNTER:', counter, "CASHIER:", "SUPERADMIN").replace(" ", " "), textStyle))Story.append(Paragraph("MN INV NO&DT: {0:<13s}{1:%d/%m/%Y} ".format(ourInvoiceNum, billingTime).replace(" ", " "), textStyle))drawLine(Story, lineStyle)Story.append(Paragraph("{0:<13s}{1:<27s}".format("CUSTOMER ID:", customerId).replace(" ", " "), textStyle))Story.append(Paragraph("{0:<6s}{1:<34s}".format("NAME:", customerName + " " + ourInvoiceNum).replace(" ", " "), textStyle))Story.append(Paragraph("{0:<9s}{1:<31s}".format("TEL NO.:", telNum).replace(" ", " "), textStyle))drawLine(Story, lineStyle)Story.append(Paragraph("ITEM" + " "*12 + "LOT NUMBER<br></br>" + \" ITEM NAME<br></br>" + \" "*5 + "QTY" + " "*21 + "AMOUNT(INR)", textStyle))drawLine(Story, lineStyle)Story.append(Paragraph(('{0:<16s}{1:24s}').format(itemCode, lotNumber).replace(' ', ' '),textStyle))Story.append(Paragraph((' {0:<39s}').format(itemName).replace(' ', ' '),textStyle))Story.append(Paragraph(('{0:<3d}{1:>10s}{2:13.2f}{3:14.2f}').format(qty, 'PCS', unitPrice, qty*unitPrice).replace(' ', ' '),textStyle))Story.append(Paragraph(('{0:<3s}{1:37.2f}').format("VAT", vat).replace(' ', ' '),textStyle))Story.append(Paragraph(('{0:<10s}{1:30.2f}').format("ITEM TOTAL", vat + unitPrice*qty).replace(' ', ' '),textStyle))drawLine(Story, lineStyle)Story.append(Paragraph(('{0:13s}{1:>12s}{2:15.2f}').format("GROSS TOTAL:","INR", vat + unitPrice*qty).replace(' ', ' '),textStyle))drawLine(Story, lineStyle)Story.append(Paragraph(('{0:13s}{1:>12s}{2:15.2f}').format("NET TOTAL:","INR", vat + unitPrice*qty).replace(' ', ' '),textStyle))Story.append(Paragraph(('{0:13s}{1:>12s}{2:15.2f}').format("NET VAT:","INR", vat).replace(' ', ' '),textStyle))drawLine(Story, lineStyle)Story.append(Paragraph(('{0:13s}{1:>12s}{2:15.2f}').format("SPICE ONLINE:","INR", vat + unitPrice*qty).replace(' ', ' '),textStyle))drawLine(Story, lineStyle)Story.append(Paragraph(('{0:16s}{1:>4d}').format("NUMBER OF ITEMS:",qty,).replace(' ', ' '),textStyle))Story.append(Paragraph(('{0:16s}{1:>9.6f}').format("TOTAL ITEMS :",qty,).replace(' ', ' '),textStyle))Story.append(Paragraph("Goods once Sold Will not be taken back.<br></br>All Disputes subject to Delhi Jurisdiction",epilogueStyle))doc.addPageTemplates([PageTemplate(id='TwoCol',frames=[frame1]), ])#start the construction of the pdfdoc.build(Story)def change_shipping_address(orderId, line1, line2, city, state, pin):order = Order.get_by(id = orderId)if order:ordersList = get_orders_for_transaction(order.transaction_id, order.customer_id)logistics_client = LogisticsClient().get_client()for order in ordersList:if order.logisticsTransactionId is None:order.customer_address1 = line1order.customer_address2 = line2order.customer_city = cityorder.customer_state = state# Start:- Added/Modified by Manish Sharma on 13 May 2013 for Change Shipping Address functionalityif order.customer_pincode != pin :type = DeliveryType.PREPAIDif order.cod:type = DeliveryType.CODif not logistics_client.isAlive():logistics_client = LogisticsClient().get_client()logistics_info = logistics_client.getLogisticsEstimation(order.lineitems[0].item_id, pin, type)# Check for new estimate. Raise exception if new address is not serviceableif logistics_info.deliveryTime == -1:raise TransactionServiceException(1, 'Location not serviceable')# COD services are not available everywhereif order.cod:if not logistics_info.codAllowed:raise TransactionServiceException(2, 'COD service not available')logistics_info_new = logistics_client.getLogisticsInfo(pin, order.lineitems[0].item_id, type, PickUpType.COURIER)#Start:- Added by Manish Sharma for FedEx Integration- Shipment Creation on 31-Jul-2013#order.tracking_id = logistics_info_new.airway_billno#order.airwaybill_no = logistics_info_new.airway_billno'''if logistics_info_new.providerId !=7:awb_number = logistics_client.getEmptyAWB(logistics_info_new.providerId, type)order.tracking_id = awb_numberorder.airwaybill_no = awb_number'''#End:- Added by Manish Sharma for FedEx Integration- Shipment Creation on 31-Jul-2013order.logistics_provider_id = logistics_info_new.providerIdcurrent_time = datetime.datetime.now()logistics_info.deliveryTime = adjust_delivery_time(current_time, logistics_info.deliveryTime)logistics_info.shippingTime = adjust_delivery_time(current_time, logistics_info.shippingTime)logistics_info.deliveryDelay = adjust_delivery_time(current_time, (logistics_info.shippingTime+logistics_info.deliveryDelay))new_expected_shipping_time_cod = (current_time + datetime.timedelta(days=logistics_info.shippingTime)).replace(hour=COD_SHIPPING_CUTOFF_TIME, minute=0, second=0)new_expected_shipping_time_prepaid = (current_time + datetime.timedelta(days=logistics_info.shippingTime)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)if order.cod:if order.expected_shipping_time.date() == new_expected_shipping_time_cod.date() :if order.otg :order.otg = logistics_info.otgAvailableelse:if order.otg:order.otg = Falseorder.expected_shipping_time = new_expected_shipping_time_codorder.expected_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryTime)).replace(hour=COD_SHIPPING_CUTOFF_TIME, minute=0, second=0)order.courier_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryDelay)).replace(hour=COD_SHIPPING_CUTOFF_TIME, minute=0, second=0)else:if order.expected_shipping_time.date() == new_expected_shipping_time_prepaid.date() :if order.otg :order.otg = logistics_info.otgAvailableelse:if order.otg:order.otg = Falseorder.expected_shipping_time = new_expected_shipping_time_prepaidorder.expected_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryTime)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)order.courier_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryDelay)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)order.customer_pincode = pin# End:- Added/Modified by Manish Sharma on 13 May 2013 for Change Shipping Address functionalitysession.commit()return Truereturn Falsedef get_recharge_transactions(storeId):query = RechargeTransaction.query.filter(RechargeTransaction.storeId == storeId)return query.all()def get_recharge_trans(storeId, startdate,enddate, status):if startdate == -1:startdate = Noneif enddate == -1:enddate = Noneif storeId== 0:storeId = Noneif status == 0:status = Nonequery = RechargeTransaction.queryif storeId is not None:query = query.filter(RechargeTransaction.storeId == storeId)if status is not None:query = query.filter(RechargeTransaction.status == status)if status == RechargeOrderStatus.RECHARGE_FAILED_REFUNDED :query.filter(cast(RechargeTransaction.responseTime, DATE) == enddate)else :if startdate is not None and enddate is not None:startdate = to_py_date(startdate).date()enddate = to_py_date(enddate).date()if startdate == enddate:query = query.filter(cast(RechargeTransaction.transactionTime, DATE) == enddate)elif enddate < startdate:query = query.filter(between(cast(RechargeTransaction.transactionTime, DATE), enddate, startdate))else:query = query.filter(between(cast(RechargeTransaction.transactionTime, DATE), startdate, enddate))elif startdate is not None:startdate = to_py_date(startdate).date()query = query.filter(cast(RechargeTransaction.transactionTime, DATE) >= startdate)elif enddate is not None:enddate = to_py_date(enddate).date()query = query.filter(cast(RechargeTransaction.transactionTime, DATE) <= enddate)return query.all()def update_recharge_transaction_status(id, status):rechargeTransaction = RechargeTransaction.get_by(id=id)if rechargeTransaction.status == status:print "Same updation of recharge transaction status"returnif status in (RechargeOrderStatus.RECHARGE_FAILED_REFUNDED, RechargeOrderStatus.RECHARGE_FAILED):rechargeTransaction.status = statusrechargeTransaction.responseTime = datetime.datetime.now()store = HotspotStore.get_by(id=rechargeTransaction.storeId)wallet = WalletForCompany.query.filter(WalletForCompany.companyId==store.companyId).with_lockmode("update").one()wh = WalletHistoryForCompany()wh.walletId = wallet.idwh.amount = rechargeTransaction.amountwh.transactionTime = rechargeTransaction.responseTimewh.openingBal = wallet.amountwh.closingBal = wallet.amount + wh.amountwh.referenceNumber = rechargeTransaction.idwh.description = "Credited amount"wallet.amount = wallet.amount + rechargeTransaction.amountstore.availableLimit = store.availableLimit + rechargeTransaction.amountstore.collectedAmount = store.collectedAmount - rechargeTransaction.amount + rechargeTransaction.discountsession.commit()if status == RechargeOrderStatus.RECHARGE_SUCCESSFUL:rechargeTransaction.status = RechargeOrderStatus.RECHARGE_SUCCESSFULrechargeTransaction.responseTime = datetime.datetime.now()rechargeTransaction.invoiceNumber = get_next_invoice_number(OrderType.RCH4HOTSPOT)session.commit()def create_recharge_transaction(t_recharge):dt = datetime.datetime.now() - datetime.timedelta(minutes=10)txns = RechargeTransaction.query.filter(RechargeTransaction.deviceNum == t_recharge.deviceNum).filter(RechargeTransaction.transactionTime > dt).all()if txns:raise TransactionServiceException(898, "In last 10 minutes you had already recharged this mobile number. Please try after sometime.")rechargeTransaction = RechargeTransaction()rechargeTransaction.amount = t_recharge.amountrechargeTransaction.circleId = t_recharge.circleIdrechargeTransaction.deviceNum = t_recharge.deviceNumrechargeTransaction.deviceType = t_recharge.deviceTyperechargeTransaction.discount = t_recharge.discountrechargeTransaction.email = t_recharge.emailrechargeTransaction.name = t_recharge.namerechargeTransaction.cafNum = t_recharge.cafNumrechargeTransaction.simNum = t_recharge.simNumrechargeTransaction.isFrc = t_recharge.isFrcrechargeTransaction.status = RechargeOrderStatus.INITrechargeTransaction.storeId = t_recharge.storeIdrechargeTransaction.transactionTime = datetime.datetime.now()rechargeTransaction.operatorId = t_recharge.operatorIdrechargeTransaction.plan = t_recharge.planrechargeTransaction.ipAddress = t_recharge.ipAddressrechargeTransaction.paymentAmount = t_recharge.paymentAmountrechargeTransaction.payMethod = t_recharge.payMethodstore = HotspotStore.get_by(id=rechargeTransaction.storeId)if not rechargeTransaction.circleId:rechargeTransaction.circleId = store.circleIdwallet = WalletForCompany.query.filter(WalletForCompany.companyId==store.companyId).with_lockmode("update").one()if store.availableLimit < rechargeTransaction.amount or wallet.amount < rechargeTransaction.amount:raise TransactionServiceException(898, "Either wallet amount for company or available limit for store is less than recharge amount.")wh = WalletHistoryForCompany()wh.walletId = wallet.idwh.amount = -rechargeTransaction.amountwh.transactionTime = rechargeTransaction.transactionTimewh.openingBal = wallet.amountwh.closingBal = wallet.amount + wh.amountwh.description = "Debited amount"wallet.amount = wallet.amount - rechargeTransaction.amountstore.availableLimit = store.availableLimit - rechargeTransaction.amountstore.collectedAmount = store.collectedAmount + rechargeTransaction.amount - rechargeTransaction.discountsession.commit()wh.referenceNumber = rechargeTransaction.idsession.commit()strProviderCode = get_provider_code(rechargeTransaction.operatorId)if rechargeTransaction.deviceType == 1:rtype = 'MTP'else:rtype = 'RCH'if rechargeTransaction.operatorId not in (getSyncOperatorsForRecharge()):rechargeMode = RechargeMode._NAMES_TO_VALUES.get('ASYNC')else:rechargeMode = RechargeMode._NAMES_TO_VALUES.get('SYNC')retStatus, retCode, spiceTID, description, aggTID, providerTID = RechargeService.rechargeDevice(rechargeTransaction.id, rtype, strProviderCode, rechargeTransaction.deviceNum, rechargeTransaction.amount, rechargeTransaction.plan, store.hotspotId, rechargeMode)rechargeTransaction.spiceTID = spiceTIDrechargeTransaction.aggTID = aggTIDrechargeTransaction.providerTID = providerTIDrechargeTransaction.responseTime = datetime.datetime.now()rechargeTransaction.description = descriptionif rechargeMode == RechargeMode._NAMES_TO_VALUES.get('SYNC'):if retCode == '00' and retStatus == 'S':rechargeTransaction.status = RechargeOrderStatus.RECHARGE_SUCCESSFULrechargeTransaction.invoiceNumber = get_next_invoice_number(OrderType.RCH4HOTSPOT)elif retCode in ('STO', 'US', 'UP', 'STP') and retStatus == 'S':rechargeTransaction.status = RechargeOrderStatus.RECHARGE_UNKNOWNelse:rechargeTransaction.status = RechargeOrderStatus.RECHARGE_FAILEDif retCode in ('SVAI', 'SVIA', 'AI', 'IA', 'EAI', 'SVEAI'):rechargeTransaction.description = "Invalid Amount"elif retCode in ('ECL', 'SVECL', 'SCL'):rechargeTransaction.description = "Customer Exceeded Daily Limit"elif retCode in ('CI', 'ECI', 'ESP', 'SVCI', 'SVECI', 'SVESP', 'SV_ECI', 'SV ECI'):rechargeTransaction.description = "Invalid Device Number"store = HotspotStore.get_by(id=rechargeTransaction.storeId)wallet = WalletForCompany.query.filter(WalletForCompany.companyId==store.companyId).with_lockmode("update").one()wh = WalletHistoryForCompany()wh.walletId = wallet.idwh.amount = rechargeTransaction.amountwh.transactionTime = rechargeTransaction.responseTimewh.openingBal = wallet.amountwh.closingBal = wallet.amount + wh.amountwh.referenceNumber = rechargeTransaction.idwh.description = "Credited amount"wallet.amount = wallet.amount + rechargeTransaction.amountstore.availableLimit = store.availableLimit + rechargeTransaction.amountstore.collectedAmount = store.collectedAmount - rechargeTransaction.amount + rechargeTransaction.discountelse:rechargeTransaction.status = RechargeOrderStatus.RECHARGE_IN_PROCESSrechargeTransaction.description = 'Recharge In Process'session.commit()return rechargeTransactiondef get_frcs(circleId, operatorId):query = FRC.query.filter(FRC.circleId == circleId)if(operatorId > 0):query = query.filter(FRC.operatorId == operatorId)frcs = query.all()if frcs is None:return []return frcsdef get_recharge_transaction(rechargeId):recharge = RechargeTransaction.get_by(id = rechargeId)if not recharge:raise TransactionServiceException(108, "no such transaction")return rechargedef get_hotspot_store(id, hotspotid):store = Noneif id > 0:store = HotspotStore.query.filter(HotspotStore.id == id).first()elif len(hotspotid) > 0:store = HotspotStore.query.filter(HotspotStore.hotspotId == hotspotid).first()else:raise TransactionServiceException(119, 'No such store')if store:return storeelse:raise TransactionServiceException(119, 'No such store')def get_circle(id, code):circle = Noneif id > 0:circle = TelecomCircle.get_by(id = id)elif len(code) > 0:circle = TelecomCircle.get_by(code = code)else:raise TransactionServiceException(119, 'No such circle')if circle:return circleelse:raise TransactionServiceException(119, 'No such circle')def retrieve_hotspot_recharge_invoice(id):recharge = RechargeTransaction.get_by(id = id)filename = "/tmp/recharge" + str(recharge.invoiceNumber) + ".pdf"operator = ServiceProvider.get_by(id = recharge.operatorId).nameamount = recharge.amounttelNum = "+91 " + str(recharge.deviceNum)customerName = recharge.nameinvNum = str(recharge.invoiceNumber)billingTime = recharge.responseTimepayMethod = recharge.payMethodreturn __printRechargeInvoice(filename, operator, amount, telNum, customerName, invNum, billingTime, payMethod)def split_freebie_order(order_id, splitReason, shippingDate):order = get_order(order_id)freebie_order = Order()freebie_order.transaction = order.transactionfreebie_order.customer_id = order.customer_idfreebie_order.customer_email = order.customer_emailfreebie_order.customer_name = order.customer_namefreebie_order.customer_pincode = order.customer_pincodefreebie_order.customer_address1 = order.customer_address1freebie_order.customer_address2 = order.customer_address2freebie_order.customer_city = order.customer_cityfreebie_order.customer_state = order.customer_statefreebie_order.customer_mobilenumber = order.customer_mobilenumberfreebie_order.total_weight = order.total_weightfreebie_order.total_amount = 0.01freebie_order.status = OrderStatus.SUBMITTED_FOR_PROCESSINGfreebie_order.statusDescription = "In Process";freebie_order.created_timestamp = datetime.datetime.now()freebie_order.cod = 0freebie_order.orderType = OrderType.B2Cfreebie_order.pickupStoreId = 0freebie_order.otg = 0freebie_order.insurer = 0freebie_order.insuranceAmount = 0freebie_order.source = order.sourcelogistics_client = LogisticsClient().get_client()logistics_info = logistics_client.getLogisticsInfo(order.customer_pincode, order.freebieItemId, DeliveryType.PREPAID, PickUpType.COURIER)freebie_order.logistics_provider_id = logistics_info.providerId;freebie_order.tracking_id = logistics_info.airway_billnofreebie_order.airwaybill_no = logistics_info.airway_billnonew_shipping_date = max(to_py_date(shippingDate),order.expected_delivery_time+datetime.timedelta(hours=72))#freebie_order.expected_delivery_time = (to_py_date(shippingDate)+datetime.timedelta(days=logistics_info.deliveryTime)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)freebie_order.expected_delivery_time = (new_shipping_date+datetime.timedelta(days=logistics_info.deliveryTime)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)freebie_order.promised_delivery_time = order.promised_delivery_timefreebie_order.expected_shipping_time = new_shipping_datefreebie_order.promised_shipping_time = order.promised_shipping_timeinventory_client = InventoryClient().get_client()item_availability = inventory_client.getItemAvailabilityAtLocation(order.freebieItemId,1)freebie_order.warehouse_id = item_availability[2]freebie_order.fulfilmentWarehouseId = item_availability[0]catalog_client = CatalogClient().get_client()item = catalog_client.getItem(order.freebieItemId)freebie_order.total_weight = item.weightlitem = LineItem()litem.item_id = item.idlitem.productGroup = item.productGrouplitem.brand = item.brandlitem.model_number = item.modelNumberlitem.model_name = item.modelNamelitem.color = item.colorlitem.extra_info = "Freebie Order for Order ID " + str(order.id)litem.quantity = 1litem.unit_price = 0.01litem.unit_weight = item.weightlitem.total_price = 0.01litem.total_weight = item.weightlitem.vatRate = 5.0freebie_order.lineitems.append(litem)order.freebieItemId = 0session.commit()order.lineitems[0].extra_info = "Parent Order for Order ID " + str(freebie_order.id)inventory_client = InventoryClient().get_client()inventory_client.reserveItemInWarehouse(freebie_order.lineitems[0].item_id, item_availability[0], sourceId, freebie_order.id, to_java_date(freebie_order.created_timestamp), to_java_date(freebie_order.promised_shipping_time), 1)parentOrderAttribute = Attribute()parentOrderAttribute.orderId = freebie_order.idparentOrderAttribute.name = "parentOrderIdForFreebie"parentOrderAttribute.value = str(order.id)freebieOrderAttribute = Attribute()freebieOrderAttribute.orderId = order.idfreebieOrderAttribute.name = "freebieOrderId"freebieOrderAttribute.value = str(freebie_order.id)session.commit()'''crmServiceClient = CRMClient().get_client()ticket =Ticket()activity = Activity()description = "Creating Ticket for " + splitReason + " Order"ticket.creatorId = 1ticket.assigneeId = 34ticket.category = TicketCategory.OTHERticket.priority = TicketPriority.HIGHticket.status = TicketStatus.OPENticket.description = descriptionticket.orderId = order_idactivity.creatorId = 1activity.ticketAssigneeId = ticket.assigneeIdactivity.type = ActivityType.OTHERactivity.description = descriptionactivity.ticketCategory = ticket.categoryactivity.ticketDescription = ticket.descriptionactivity.ticketPriority = ticket.priorityactivity.ticketStatus = ticket.statusticket.customerId= order.customer_idticket.customerEmailId = order.customer_emailticket.customerMobileNumber = order.customer_mobilenumberticket.customerName = order.customer_nameactivity.customerId = ticket.customerIdactivity.customerEmailId = order.customer_emailactivity.customerMobileNumber = order.customer_mobilenumberactivity.customerName = order.customer_namecrmServiceClient.insertTicket(ticket, activity)'''return to_t_order(freebie_order)def __printRechargeInvoice(filename, operator, amount, telNum, customerName, invNum, billingTime, payMethod):PAGE_HEIGHT=defaultPageSize[1];styles = getSampleStyleSheet()styles.add(ParagraphStyle(name='prologue', alignment=TA_CENTER, fontName="Courier", rightIndent = 5, fontSize=10), alias='sH')styles.add(ParagraphStyle(name='text', alignment=TA_JUSTIFY, fontName="Courier", fontSize=10), alias='text')styles.add(ParagraphStyle(name='line', alignment=TA_CENTER, fontName="Courier", fontSize=10), alias='line')styles.add(ParagraphStyle(name='epilogue', alignment=TA_CENTER, fontName="Courier", leftIndent = 30, rightIndent=36, fontSize=10), alias='ep')Story = []prologueStyle = styles["prologue"]lineStyle = styles["line"]textStyle = styles["text"]epilogueStyle = styles["epilogue"]doc = BaseDocTemplate(filename,showBoundary=0)#Two Columnsframe1 = Frame(58, doc.bottomMargin, doc.width/2 + 25, doc.height + 7, id='col1')Story.append(Paragraph("""Spice Retail Limited<br></br>C/O,PIBCO LIMITED,Basement,Punjsons<br></br>2,Kalkaji Industrial Area,New Delhi<br></br>.<br></br>TIN NO. 07430284979<br></br>Service Tax No:AAACM0294PST001<br></br><br></br><br></br>""", prologueStyle))drawLine(Story, lineStyle)Story.append(Paragraph('{0:7s}{1:>11s}{2: %d/%m/%Y %H:%M:%S}'.format("INV NO:", invNum, billingTime).replace(" ", " "), textStyle))drawLine(Story, lineStyle)Story.append(Paragraph("{0:<6s}{1:<34s}".format("NAME:", customerName).replace(" ", " "), textStyle))Story.append(Paragraph("{0:<9s}{1:<31s}".format("TEL NO.:", telNum).replace(" ", " "), textStyle))Story.append(Paragraph("{0:<9s}{1:<31s}".format("PAYMENT MODE:", PayMethod._VALUES_TO_NAMES[payMethod]).replace(" ", " "), textStyle))drawLine(Story, lineStyle)Story.append(Paragraph(('{0:<16s}{1:>13s}{2:11.2f}').format(operator, "RECHARGE", amount).replace(' ', ' '),textStyle))drawLine(Story, lineStyle)doc.addPageTemplates([PageTemplate(id='TwoCol',frames=[frame1]), ])#start the construction of the pdfdoc.build(Story)try:fileToSend = open(filename, "rb")pdfFile = fileToSend.read()except:return bin(0)return pdfFiledef get_recharge_transactions_by_number(number, storeId):query = RechargeTransaction.query.filter(RechargeTransaction.deviceNum == number)query = query.filter(RechargeTransaction.storeId == storeId)return query.all()def update_hotspot_store_password(storeId, password):store = Noneif password is None:return Falseif storeId:store = HotspotStore.query.filter(HotspotStore.id == storeId).first()if store:store.password = passwordsession.commit()return Truereturn Falsedef get_source_detail(source):detail = SourceDetail.get_by(id=source)if not detail:raise TransactionServiceException(108, "no such source")return detaildef get_all_circles():circles = TelecomCircle.query.all();if not circles:circles = []return circlesdef delete_frcs(frcIdsToDelete):toReturn = Falseif frcIdsToDelete:for frcId in frcIdsToDelete:frc = FRC.get_by(id = frcId)if frc:frc.delete()toReturn = Truesession.commit()return toReturnelse:return toReturndef topup_company_wallet(companyId, amount):wallet = WalletForCompany.query.filter(WalletForCompany.id == companyId).with_lockmode("update").one()company = Company.get_by(id = companyId)wh = WalletHistoryForCompany()wh.walletId = wallet.idwh.openingBal = wallet.amountwh.closingBal = wallet.amount + amountwh.amount = amountwh.transactionTime = datetime.datetime.now()wh.referenceNumber = get_next_invoice_number(OrderType.WALLETCREDIT)wh.description = "Wallet Credited"wallet.amount += amountsession.commit()mail("cnc.center@shop2020.in", "5h0p2o2o", [ "kshitij.sood@shop2020.in","pardeep.panwar@spiceretail.co.in","adarsh.verma@spiceretail.co.in","j.p.gupta@shop2020.in", "rajneesh.arora@shop2020.in", "amit.tyagi@spiceretail.co.in"] , company.name + " wallet topped up by " + str(amount) + " rupees.", "", [], [], [])return wallet.amountdef get_wallet_balance_for_company(companyId):return WalletForCompany.get_by(companyId = companyId).amountdef add_amazon_order(amazonOrder):amazon_order = AmazonOrder()amazon_order.orderId = amazonOrder.orderIdamazon_order.amazonOrderCode = amazonOrder.amazonOrderCodeamazon_order.amazonOrderItemCode = amazonOrder.amazonOrderItemCodeamazon_order.transactionId = amazonOrder.transactionIdamazon_order.item_id= amazonOrder.item_idamazon_order.status= amazonOrder.statusamazon_order.purchaseDateOnAmazon= to_py_date(amazonOrder.purchaseDateOnAmazon);session.commit()def update_amazon_order_status(order_id,status):row = AmazonOrder.get_by(orderId=order_id)row.status=statussession.commit()return Truedef get_amazon_orders_marked_sent():return AmazonOrder.query.filter(AmazonOrder.status=='Order-Payment-Success').all()def get_amazon_orders_shipped():amazonShippedOrders = []###toDate = datetime.datetime.now()###fromDate = toDate-timedelta(days = interval-1, hours=toDate.hour, minutes=toDate.minute, seconds=toDate.second)orders = get_amazon_orders_marked_sent()if not orders:return amazonShippedOrdersfor order in orders:row = Order.query.filter(Order.id == order.orderId).first()if row.shipping_timestamp:amazonShippedOrders.append(to_t_order(row))return amazonShippedOrdersdef get_amazon_orders_cancelled(interval):amazonCancelledOrders = []toDate = datetime.datetime.now()fromDate = toDate-timedelta(days = interval-1, hours=toDate.hour, minutes=toDate.minute, seconds=toDate.second)orders = get_amazon_orders_marked_sent()for order in orders:row = Order.query.filter(Order.refund_timestamp.between (fromDate,toDate)).filter(Order.id==order.orderId).first()if row is None:continueif ( row.status == 15 or row.status == 18 or row.status == 34 ):amazonCancelledOrders.append(to_t_order(row))return amazonCancelledOrdersdef get_amazon_order(order_id):return AmazonOrder.get_by(orderId=order_id)def get_amazon_order_by_amazonorderid(amazonOrderId):return AmazonOrder.query.filter(AmazonOrder.amazonOrderCode==amazonOrderId)def get_amazon_orders_to_acknowledge(source):orderstatus = []orderstatus.append('Order-Payment-Success')orderstatus.append('Order-Payment-Failure')return session.query(AmazonOrder.amazonOrderCode,AmazonOrder.amazonOrderItemCode,AmazonOrder.status,AmazonOrder.transactionId,func.count(AmazonOrder.orderId))\.join((Order, Order.id==AmazonOrder.orderId)).filter(AmazonOrder.status.in_(orderstatus)).filter(Order.source==source).group_by(AmazonOrder.amazonOrderItemCode,AmazonOrder.status).all()def change_amazon_order_status(amazonOrderCode,status):for order in AmazonOrder.query.filter(AmazonOrder.amazonOrderCode==amazonOrderCode):order.status = statussession.commit()def get_orders_for_store(orderId, storeId, startDate, endDate, statuses):orders = []query = Order.queryif storeId < 1:return orderselif orderId > 0:query = query.filter(Order.id == orderId)else :if startDate:query = query.filter(cast(Order.created_timestamp, DATE) >= startDate.date())if endDate:query = query.filter(cast(Order.created_timestamp, DATE) <= endDate.date())if len(statuses) > 0:query = query.filter(Order.status.in_(statuses))orders = query.filter(Order.storeId == storeId).all()return ordersdef get_store_order_advance_invoice(orderId, storeId):order = Order.get_by(id = orderId)storeOrderDetail = StoreOrderDetail.query.filter(StoreOrderDetail.orderId == orderId).filter(StoreOrderDetail.storeId == storeId).first()store = HotspotStore.get_by(id = storeId)modelName = " "modelNumber = " "color = " "if order.lineitems[0].model_name:modelName = modelName + order.lineitems[0].model_nameif order.lineitems[0].model_number:modelNumber = modelNumber + order.lineitems[0].model_numberif order.lineitems[0].color:color = color + order.lineitems[0].colorproduct = order.lineitems[0].brand + modelName + modelNumber + coloradvanceAmount = order.advanceAmounttotalAmount = order.total_amountdelivery = order.expected_delivery_timecustomerName = order.customer_namecustomerAdd1 = order.customer_address1customerAdd2 = order.customer_address2customerCity = order.customer_citycustomerState = order.customer_statecustomerMobile = order.customer_mobilenumbercustomerPin = order.customer_pincodeinCash = storeOrderDetail.cashAmountbyCard = storeOrderDetail.cardAmountif order.status in (15, 34) and (storeOrderDetail.cashRefundAmount > 0 or storeOrderDetail.cashRefundAmount > 0):filename = "/tmp/order-refund-" + str(order.id) + ".pdf"inCash = storeOrderDetail.cashRefundAmountbyCard = storeOrderDetail.cardRefundAmountreturn __printStoreOrderCancellationReceipt(store, order.id, filename, customerName, customerAdd1, customerAdd2, customerCity, customerState, customerMobile, customerPin, product, advanceAmount,inCash, byCard, order.created_timestamp.date(), order.refund_timestamp.date())else:filename = "/tmp/order-" + str(order.id) + ".pdf"#payMethod = recharge.payMethod# if order.status == 15 or order.status == 34:# return __printStoreOrderAdvanceInvoice(filename, product, advanceAmount, totalAmount, customerName, delivery, mode, customerAdd1, customerAdd2, customerCity, customerState, customerMobile, customerPin)return __printStoreOrderAdvanceInvoice(store, order.id, filename, product, advanceAmount, totalAmount, customerName, delivery, inCash, byCard, customerAdd1, customerAdd2, customerCity, customerState, customerMobile, customerPin, order.created_timestamp.date())def __printStoreOrderCancellationReceipt(store, orderId, filename, customerName, customerAdd1, customerAdd2, customerCity, customerState, customerMobile, customerPin, product, advanceAmount,inCash, byCard, createdDate, cancelDate):PAGE_HEIGHT=defaultPageSize[1];styles = getSampleStyleSheet()styles.add(ParagraphStyle(name='prologue', alignment=TA_CENTER, fontName="Courier", rightIndent = 5, fontSize=10), alias='sH')styles.add(ParagraphStyle(name='text', alignment=TA_JUSTIFY, fontName="Courier", fontSize=10), alias='text')styles.add(ParagraphStyle(name='line', alignment=TA_CENTER, fontName="Courier", fontSize=10), alias='line')styles.add(ParagraphStyle(name='epilogue', alignment=TA_CENTER, fontName="Courier", leftIndent = 30, rightIndent=36, fontSize=10), alias='ep')Story = []prologueStyle = styles["prologue"]lineStyle = styles["line"]textStyle = styles["text"]epilogueStyle = styles["epilogue"]doc = BaseDocTemplate(filename,showBoundary=0)#Two Columnsframe1 = Frame(58, doc.bottomMargin, doc.width/2 + 25, doc.height + 7, id='col1')Story.append(Paragraph(store.line1, prologueStyle))Story.append(Paragraph(store.line2 + ', ' + store.city, prologueStyle))Story.append(Paragraph(store.state + ' - ' + store.pin, prologueStyle))drawLine(Story, lineStyle)Story.append(Paragraph("{0:^39s}".format("*** ADVANCE REFUND RECEIPT ***").replace(" ", " "), textStyle))drawLine(Story, lineStyle)Story.append(Paragraph("{0:<6s}{1:<34s}".format("NAME:", customerName).replace(" ", " "), textStyle))Story.append(Paragraph("{0:<10s}{1:<29s}".format("MOBILE:", customerMobile).replace(" ", " "), textStyle))Story.append(Paragraph("{0:<10s}{1:<29s}".format("ORDER ID:", str(orderId)).replace(" ", " "), textStyle))Story.append(Paragraph("{0:<20s}{1: %d/%m/%Y}".format("CURRENT DATE:", datetime.datetime.now().date()).replace(" ", " "), textStyle))Story.append(Paragraph("{0:<20s}{1: %d/%m/%Y}".format("ORDER DATE:", createdDate).replace(" ", " "), textStyle))Story.append(Paragraph("{0:<20s}{1: %d/%m/%Y}".format("CANCELLATION DATE:", cancelDate).replace(" ", " "), textStyle))drawLine(Story, lineStyle)Story.append(Paragraph("{0:^39s}".format("DELIVERY ADDRESS").replace(" ", " "), textStyle))drawLine(Story, lineStyle)Story.append(Paragraph(customerAdd1, textStyle))if len(customerAdd2) > 0:Story.append(Paragraph(customerAdd2, textStyle))Story.append(Paragraph(customerCity, textStyle))Story.append(Paragraph(customerState + " - " + customerPin, textStyle))drawLine(Story, lineStyle)Story.append(Paragraph("{0:^39s}".format("PRODUCT NAME").replace(" ", " "), textStyle))drawLine(Story, lineStyle)Story.append(Paragraph(product, textStyle))drawLine(Story, lineStyle)Story.append(Paragraph(('{0:<20s}{1:>19.2f}').format("ADVANCE AMOUNT: ", advanceAmount).replace(' ', ' '),textStyle))Story.append(Paragraph(('{0:<30s}{1:>9.2f}').format("LESS-CANCELLATION CHARGES: ", advanceAmount-inCash-byCard).replace(' ', ' '),textStyle))Story.append(Paragraph(('{0:<30s}{1:>9.2f}').format("AMOUNT TO BE REFUNDED: ", inCash+byCard).replace(' ', ' '),textStyle))if inCash > 0:Story.append(Paragraph(('{0:>20s}{1:>19.2f}').format("REFUND IN CASH: ", inCash).replace(' ', ' '),textStyle))if byCard > 0:Story.append(Paragraph(('{0:>20s}{1:>19.2f}').format("REFUND BY CARD: ", byCard).replace(' ', ' '),textStyle))drawLine(Story, lineStyle)Story.append(Paragraph("CUSTOMER SIGNATURE :", textStyle))Story.append(Paragraph(" ", textStyle))drawLine(Story, lineStyle)drawLine(Story, lineStyle)Story.append(Paragraph("Terms & Conditions:", textStyle))Story.append(Paragraph("* Original copy of 'Advance Receipt' Shall be provided by Customer to get the refund",textStyle))Story.append(Paragraph("* All disputes subject to Delhi jusrisdiction",textStyle))drawLine(Story, lineStyle)Story.append(Paragraph(('{0:<20s}{1:>19s}').format("Customer care : ", "0120-6744700").replace(' ', ' '),textStyle))drawLine(Story, lineStyle)doc.addPageTemplates([PageTemplate(id='TwoCol',frames=[frame1]), ])#start the construction of the pdfdoc.build(Story)try:fileToSend = open(filename, "rb")pdfFile = fileToSend.read()except:return bin(0)return pdfFiledef __printStoreOrderAdvanceInvoice(store, orderId, filename, product, advanceAmount, totalAmount, customerName, delivery, inCash, byCard, customerAdd1, customerAdd2, customerCity, customerState, customerMobile, customerPin, createdDate):PAGE_HEIGHT=defaultPageSize[1];styles = getSampleStyleSheet()styles.add(ParagraphStyle(name='prologue', alignment=TA_CENTER, fontName="Courier", rightIndent = 5, fontSize=10), alias='sH')styles.add(ParagraphStyle(name='text', alignment=TA_JUSTIFY, fontName="Courier", fontSize=10), alias='text')styles.add(ParagraphStyle(name='line', alignment=TA_CENTER, fontName="Courier", fontSize=10), alias='line')styles.add(ParagraphStyle(name='epilogue', alignment=TA_CENTER, fontName="Courier", leftIndent = 30, rightIndent=36, fontSize=10), alias='ep')Story = []prologueStyle = styles["prologue"]lineStyle = styles["line"]textStyle = styles["text"]epilogueStyle = styles["epilogue"]doc = BaseDocTemplate(filename,showBoundary=0)#Two Columnsframe1 = Frame(58, doc.bottomMargin, doc.width/2 + 25, doc.height + 7, id='col1')Story.append(Paragraph(store.line1, prologueStyle))Story.append(Paragraph(store.line2 + ', ' + store.city, prologueStyle))Story.append(Paragraph(store.state + ' - ' + store.pin, prologueStyle))drawLine(Story, lineStyle)Story.append(Paragraph("{0:^39s}".format("*** ADVANCE RECEIPT ***").replace(" ", " "), textStyle))drawLine(Story, lineStyle)Story.append(Paragraph("{0:^39s}".format("DELIVERY ADDRESS").replace(" ", " "), textStyle))drawLine(Story, lineStyle)Story.append(Paragraph(customerAdd1, textStyle))if len(customerAdd2) > 0:Story.append(Paragraph(customerAdd2, textStyle))Story.append(Paragraph(customerCity, textStyle))Story.append(Paragraph(customerState + " - " + customerPin, textStyle))drawLine(Story, lineStyle)Story.append(Paragraph("{0:<6s}{1:<34s}".format("NAME:", customerName).replace(" ", " "), textStyle))Story.append(Paragraph("{0:<10s}{1:<29s}".format("MOBILE:", customerMobile).replace(" ", " "), textStyle))Story.append(Paragraph("{0:<10s}{1:<12s}{2:7s}{3: %d/%m/%Y}".format("ORDER ID:", str(orderId), "DATE:", createdDate).replace(" ", " "), textStyle))Story.append(Paragraph("{0:<20s}{1: %d/%m/%Y}".format("CURRENT DATE:", datetime.datetime.now().date()).replace(" ", " "), textStyle))Story.append(Paragraph("{0:<20s}{1: %d/%m/%Y}".format("EXPECTED DELIVERY:", delivery).replace(" ", " "), textStyle))drawLine(Story, lineStyle)Story.append(Paragraph("{0:^39s}".format("PRODUCT NAME").replace(" ", " "), textStyle))drawLine(Story, lineStyle)Story.append(Paragraph("{0:<39s}".format(product).replace(" ", " "), textStyle))drawLine(Story, lineStyle)Story.append(Paragraph(('{0:<20s}{1:>19.2f}').format("TOTAL PRICE: ", totalAmount).replace(' ', ' '),textStyle))Story.append(Paragraph(('{0:<20s}{1:>19.2f}').format("ADVANCE AMOUNT: ", advanceAmount).replace(' ', ' '),textStyle))if inCash > 0:Story.append(Paragraph(('{0:>13s}{1:>26.2f}').format("IN CASH: ", inCash).replace(' ', ' '),textStyle))if byCard > 0:Story.append(Paragraph(('{0:>13s}{1:>26.2f}').format("BY CARD: ", byCard).replace(' ', ' '),textStyle))Story.append(Paragraph(('{0:<20s}{1:>19.2f}').format("BALANCE TO BE PAID: ", (totalAmount - advanceAmount)).replace(' ', ' '),textStyle))drawLine(Story, lineStyle)Story.append(Paragraph("Terms & Conditions:", textStyle))Story.append(Paragraph("* In case of cancellation of order on customer request, 10% of product amount subject to minimum Rs 500/- shall be deducted as cancellation charges. Customer shall provide original copy of 'Advance Receipt' to get the balance amount as refund",textStyle))Story.append(Paragraph("* Balance amount as mentioned above to be paid at the time of delivery of product to courier agency. Refusal to accept the product delivered through courier shall be deemed as cancellation of order and cancellation charges shall become applicable.",textStyle))Story.append(Paragraph("* The product as mentioned above shall be made available to the customer, subject to its availability from the manufacturer",textStyle))Story.append(Paragraph("* All disputes subject to Delhi Jurisdiction",textStyle))drawLine(Story, lineStyle)Story.append(Paragraph(('{0:<20s}{1:>19s}').format("Customer care : ", "0120-6744700").replace(' ', ' '),textStyle))drawLine(Story, lineStyle)doc.addPageTemplates([PageTemplate(id='TwoCol',frames=[frame1]), ])#start the construction of the pdfdoc.build(Story)try:fileToSend = open(filename, "rb")pdfFile = fileToSend.read()except:return bin(0)return pdfFiledef add_frc(circle, operatorId, denomination, maxDiscount):frc = FRC.query.filter(FRC.circleId == circle).filter(FRC.operatorId == operatorId).filter(FRC.denomination == denomination).first()if frc:frc.maxDiscount = maxDiscountelse:frc = FRC()frc.circleId = circlefrc.denomination = denominationfrc.maxDiscount = maxDiscountfrc.operatorId = operatorIdsession.commit()return Truedef add_series(circle, operatorId, series):operatorSeriesObject = OperatorSeries.query.filter(OperatorSeries.series == series).first()if operatorSeriesObject:circleName = TelecomCircle.get_by(id = operatorSeriesObject.circleId).nameoperatorName = ServiceProvider.get_by(id = operatorSeriesObject.operatorId).namereturn "Series already exists for : " + operatorName + " in circle : " + circleNameelse :operatorSeriesObject = OperatorSeries()operatorSeriesObject.series = seriesoperatorSeriesObject.circleId = circleoperatorSeriesObject.operatorId = operatorIdsession.commit()return "Successfully saved"def save_store_order_detail(thrift_storeOrderDetail):txnId = thrift_storeOrderDetail.orderIdtxn = Transaction.get_by(id=txnId)oid = txn.orders[0].idds_storeOrderDetail = StoreOrderDetail()ds_storeOrderDetail.orderId = oidds_storeOrderDetail.advanceAmount = thrift_storeOrderDetail.advanceAmountds_storeOrderDetail.cardAmount = thrift_storeOrderDetail.cardAmountds_storeOrderDetail.cashAmount = thrift_storeOrderDetail.cashAmountds_storeOrderDetail.storeId = thrift_storeOrderDetail.storeIdds_storeOrderDetail.payStatus = thrift_storeOrderDetail.payStatusds_storeOrderDetail.cardRefundAmount = thrift_storeOrderDetail.cardRefundAmountds_storeOrderDetail.cashRefundAmount = thrift_storeOrderDetail.cashRefundAmountds_storeOrderDetail.edcBank = thrift_storeOrderDetail.edcBankds_storeOrderDetail.approvalCode = thrift_storeOrderDetail.approvalCodeds_storeOrderDetail.cardType = thrift_storeOrderDetail.cardTypesession.commit()return Truedef get_store_order_detail(orderId, storeId):storeOrderDetail = StoreOrderDetail.query.filter(StoreOrderDetail.orderId == orderId).filter(StoreOrderDetail.storeId == storeId).first()if storeOrderDetail:return storeOrderDetailelse:return StoreOrderDetail()def get_all_edc_banks():allBankNames = []edcBanks = EdcBank.query.all();for bank in edcBanks:allBankNames.append(bank.name)return allBankNamesdef save_refund_amounts_for_store_order(orderId, storeId, cashRefundAmount, cardRefundAmount):storeOrderDetail = StoreOrderDetail.query.filter(StoreOrderDetail.orderId == orderId).filter(StoreOrderDetail.storeId == storeId).first()if storeOrderDetail:storeOrderDetail.cashRefundAmount = cashRefundAmountstoreOrderDetail.cardRefundAmount = cardRefundAmountsession.commit()return Trueelse:return Falsedef get_collections_for_store(storeId, startdate, enddate):if startdate == -1:startdate = Noneif enddate == -1:enddate = Noneif storeId== 0:storeId = Noneif storeId:store = HotspotStore.get_by(id = storeId)hotspotId = store.hotspotIdquery = StoreOrderCollection.queryif storeId is not None:query = query.filter(StoreOrderCollection.hotspotId == hotspotId)else:return []if startdate is not None and enddate is not None:startdate = to_py_date(startdate).date()enddate = to_py_date(enddate).date()if startdate == enddate:query = query.filter(cast(StoreOrderCollection.pushedAt, DATE) == enddate)elif enddate < startdate:query = query.filter(between(cast(StoreOrderCollection.pushedAt, DATE), enddate, startdate))else:query = query.filter(between(cast(StoreOrderCollection.pushedAt, DATE), startdate, enddate))elif startdate is not None:startdate = to_py_date(startdate).date()query = query.filter(cast(StoreOrderCollection.pushedAt, DATE) >= startdate)elif enddate is not None:enddate = to_py_date(enddate).date()query = query.filter(cast(StoreOrderCollection.pushedAt, DATE) <= enddate)return query.filter(StoreOrderCollection.pushedToOcr == 1).all()def update_timestamp_for_amazon_order(orderDeliveryMap):for orderId,dateMap in orderDeliveryMap.iteritems():order = get_order(orderId)order.expected_delivery_time = datetime.datetime.strptime(dateMap.values()[0]+' 15:00:00', '%d-%m-%Y %H:%M:%S')order.promised_delivery_time = datetime.datetime.strptime(dateMap.values()[0]+' 15:00:00', '%d-%m-%Y %H:%M:%S')promisedShipping = datetime.datetime.strptime(dateMap.keys()[0]+' 15:00:00', '%d-%m-%Y %H:%M:%S')order.expected_shipping_time = promisedShippingorder.promised_shipping_time = promisedShippingsession.commit()return Truedef update_source_detail_timestamp(id,lastUpdatedOn):detail = get_source_detail(id)detail.lastUpdatedOn = to_py_date(lastUpdatedOn)session.commit()return Truedef get_orders_by_mobile_number(mobileNumber):return Order.query.filter(Order.customer_mobilenumber == mobileNumber).all()def get_orders_by_amazon_id(amazonId):orderIds = []amazonOrders = AmazonOrder.query.filter(AmazonOrder.amazonOrderCode == amazonId).all()for amazonOrder in amazonOrders:orderIds.append(amazonOrder.orderId)return get_order_list(orderIds)def update_freebie_item(orderId, newFreebieItemId):order = Order.get_by(id = orderId)order.freebieItemId = newFreebieItemIdsession.commit()return order#Start:- Added by Manish Sharma for FedEx Integration- Shipment Creation on 31-Jul-2013def update_order_AWB(orderId, airwayBillNo):order = Order.get_by(id = orderId)order.airwaybill_no=airwayBillNoorder.tracking_id=airwayBillNo#order.logisticsTransactionId = str(order.transaction_id)+airwayBillNosession.commit()shipmentLogisticsCostObj = TShipmentLogisticsCostDetail()shipmentLogisticsCostObj.airwayBillNo = airwayBillNoshipmentLogisticsCostObj.logisticsTransactionId = order.logisticsTransactionIdshipmentLogisticsCostObj.shipmentAmount = order.total_amountshipmentLogisticsCostObj.shipmentCodCollectionCharges = order.lineitems[0].codCollectionChargesshipmentLogisticsCostObj.shipmentLogsiticsCost = order.lineitems[0].logisticsCostshipmentLogisticsCostObj.shipmentWeight = order.total_weightshipmentLogisticsCostDetails = []shipmentLogisticsCostDetails.append(shipmentLogisticsCostObj)add_or_update_shipment_logistics_cost_details(shipmentLogisticsCostDetails)return order#End:- Added by Manish Sharma for FedEx Integration- Shipment Creation on 31-Jul-2013def get_hotspot_service_matrices():hotspotServiceMatrices = HotspotServiceMatrix.query.all()return hotspotServiceMatricesdef get_orders_by_vendor(vendors, statuses):if not len(statuses):raise TransactionServiceException(101, "Status list is empty")if not len(vendors):raise TransactionServiceException(101, "Vendor list is empty")warehouse_ids = []inventory_client = InventoryClient().get_client()for vendor in vendors:warehouses = inventory_client.getWarehouses(None, None, vendor, 0, 0)for warehouse in warehouses:warehouse_ids.append(warehouse.id)query = Order.query.filter(Order.status.in_(statuses))query = query.filter(Order.warehouse_id.in_(warehouse_ids))#raise TransactionServiceException(101, "bad warehouse id")return query.all()def __update_tax_type(order):print "updating tax type"def create_ebay_order(ebay_order):ebayOrder = EbayOrder()ebayOrder.orderId = ebay_order.orderIdebayOrder.paisaPayId = ebay_order.paisaPayIdebayOrder.salesRecordNumber = ebay_order.salesRecordNumberebayOrder.ebayListingId = ebay_order.ebayListingIdebayOrder.subsidyAmount = ebay_order.subsidyAmountebayOrder.ebayTxnDate = to_py_date(ebay_order.ebayTxnDate)ebayOrder.transactionId = ebay_order.transactionIdebayOrder.listingName = ebay_order.listingNameebayOrder.listingPrice = ebay_order.listingPricesession.commit()def get_ebay_order_by_sales_rec_number(sales_rec_number):return EbayOrder.query.filter(EbayOrder.salesRecordNumber == sales_rec_number).one()def get_ebay_order(sales_rec_number, listingId, paisa_pay_id):query = EbayOrder.queryif sales_rec_number:query = query.filter(EbayOrder.salesRecordNumber == sales_rec_number)if listingId:query = query.filter(EbayOrder.ebayListingId == listingId)if paisa_pay_id:query = query.filter(EbayOrder.paisaPayId == paisa_pay_id)return query.all()#return EbayOrder.query.filter(EbayOrder.salesRecordNumber == sales_rec_number).filter(EbayOrder.ebayListingId == listingId).one()def get_ebay_order_by_orderId(order_id):return EbayOrder.query.filter(EbayOrder.orderId == order_id).one()def update_ebay_order(ebay_order):ebayOrder = get_ebay_order_by_orderId(ebay_order.orderId)ebayOrder.subsidyAmount = ebay_order.subsidyAmountebayOrder.transactionId = ebay_order.transactionIdebayOrder.ebayTxnDate = to_py_date(ebay_order.ebayTxnDate)ebayOrder.bluedartPaisaPayRef = ebay_order.bluedartPaisaPayRefebayOrder.listingPrice = ebay_order.listingPricesession.commit()def ebay_order_exists(sales_rec_number, ebay_listing_id):try:ebayOrder = get_ebay_order_by_sales_rec_number(sales_rec_number)if ebayOrder.ebayListingId == ebay_listing_id:return Trueelse:return Falseexcept Exception as e:return Falsedef update_order_for_ebay(t_order):order = get_order(t_order.id)order.customer_id = t_order.customer_idorder.customer_name = t_order.customer_nameorder.customer_city = t_order.customer_cityorder.customer_state = t_order.customer_stateorder.customer_mobilenumber = t_order.customer_mobilenumberorder.customer_pincode = t_order.customer_pincodeorder.customer_address1 = t_order.customer_address1order.customer_address2 = t_order.customer_address2order.customer_email = t_order.customer_emailorder.logistics_provider_id = t_order.logistics_provider_idorder.airwaybill_no = t_order.airwaybill_noorder.tracking_id = t_order.tracking_idorder.status = t_order.statusorder.statusDescription = t_order.statusDescriptionorder.cod = 0order.otg = Falseorder.freebieItemId = 0order.orderType = OrderType.B2Corder.source = 6transaction = get_transaction(order.transaction_id)transaction.status = TransactionStatus.AUTHORIZEDtransaction.customer_id = t_order.customer_idsession.commit()def split_ebay_order(order_id, split_order_qty, split_order_item_id, use_power_ship):#In case of split now order is always assigned based on the website logic...Also itemId won't work for noworder = get_order(order_id)if split_order_qty >=order.lineitems[0].quantity:raise TransactionServiceException(108, "Split Quantity is greater than or equal to order quantity")if order.status not in [OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.LOW_INV_PO_RAISED, OrderStatus.LOW_INV_REVERSAL_IN_PROCESS, OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT, OrderStatus.CAPTURE_IN_PROCESS, OrderStatus.REJECTED, OrderStatus.ACCEPTED]:raise TransactionServiceException(108, "Order not allowed to be split")new_order = __clone_order(order, False, False)new_order.expected_delivery_time = order.expected_delivery_timenew_order.promised_delivery_time = order.promised_delivery_timenew_order.expected_shipping_time = order.expected_shipping_timenew_order.promised_shipping_time = order.promised_shipping_timeif use_power_ship:new_order.logistics_provider_id = order.logistics_provider_idnew_order.airwaybill_no = order.airwaybill_nonew_order.tracking_id = order.tracking_idnew_order.lineitems[0].quantity = split_order_qtynew_order.lineitems[0].total_price = new_order.lineitems[0].unit_price*split_order_qtynew_order.total_amount = new_order.lineitems[0].total_priceorder.lineitems[0].quantity = order.lineitems[0].quantity - split_order_qtyorder.lineitems[0].total_price = order.lineitems[0].unit_price * order.lineitems[0].quantityorder.total_amount = order.lineitems[0].total_pricesession.commit()return new_orderdef add_or_update_amazon_fba_sales_snapshot(amazonfbasalessnapshot):salesnapshotfordate = AmazonFbaSalesSnapshot.get_by(item_id = amazonfbasalessnapshot.item_id,dateOfSale=to_py_date(amazonfbasalessnapshot.dateOfSale).date(),fcLocation=amazonfbasalessnapshot.fcLocation)if salesnapshotfordate is None:amazon_fba_sales_snapshot = AmazonFbaSalesSnapshot()amazon_fba_sales_snapshot.dateOfSale = to_py_date(amazonfbasalessnapshot.dateOfSale).date()amazon_fba_sales_snapshot.item_id = amazonfbasalessnapshot.item_idamazon_fba_sales_snapshot.totalOrderCount = amazonfbasalessnapshot.totalOrderCountamazon_fba_sales_snapshot.amazonFbaInventory = amazonfbasalessnapshot.amazonFbaInventoryamazon_fba_sales_snapshot.isOutOfStock = amazonfbasalessnapshot.isOutOfStockamazon_fba_sales_snapshot.promotionOrderCount = amazonfbasalessnapshot.promotionOrderCountamazon_fba_sales_snapshot.totalSale = amazonfbasalessnapshot.totalSaleamazon_fba_sales_snapshot.promotionSale = amazonfbasalessnapshot.promotionSale#if amazonfbasalessnapshot.ourPrice is not None:amazon_fba_sales_snapshot.ourPriceSnapshotDate = to_py_date(amazonfbasalessnapshot.ourPriceSnapshotDate)amazon_fba_sales_snapshot.ourPrice = amazonfbasalessnapshot.ourPrice#if amazonfbasalessnapshot.salePrice is not None:amazon_fba_sales_snapshot.salePriceSnapshotDate = to_py_date(amazonfbasalessnapshot.salePriceSnapshotDate)amazon_fba_sales_snapshot.salePrice = amazonfbasalessnapshot.salePrice#if amazonfbasalessnapshot.minFbaPrice is not None:amazon_fba_sales_snapshot.minFbaPriceSnapshotDate = to_py_date(amazonfbasalessnapshot.minFbaPriceSnapshotDate)amazon_fba_sales_snapshot.minFbaPrice = amazonfbasalessnapshot.minFbaPrice#if amazonfbasalessnapshot.minMfnPrice is not None:amazon_fba_sales_snapshot.minMfnPriceSnapshotDate = to_py_date(amazonfbasalessnapshot.minMfnPriceSnapshotDate)amazon_fba_sales_snapshot.minMfnPrice = amazonfbasalessnapshot.minMfnPriceamazon_fba_sales_snapshot.fcLocation = amazonfbasalessnapshot.fcLocationelse:if(amazonfbasalessnapshot.totalOrderCount > 0):salesnapshotfordate.isOutOfStock = 0salesnapshotfordate.promotionOrderCount = amazonfbasalessnapshot.promotionOrderCountsalesnapshotfordate.totalSale = amazonfbasalessnapshot.totalSalesalesnapshotfordate.promotionSale = amazonfbasalessnapshot.promotionSalesalesnapshotfordate.totalOrderCount = amazonfbasalessnapshot.totalOrderCountsalesnapshotfordate.fcLocation = amazonfbasalessnapshot.fcLocationsession.commit()def get_amazon_fba_sales_snapshot_for_days(interval):query = session.query(Order.status, func.count(Order.id)).group_by(Order.status)date = datetime.datetime.now()toDate = date-timedelta(days = 1)fromDate = toDate-timedelta(days = interval)fbasalessnapshot = AmazonFbaSalesSnapshot.query.filter(AmazonFbaSalesSnapshot.dateOfSale.between (fromDate.date(),toDate.date())).order_by(AmazonFbaSalesSnapshot.dateOfSale).all()return fbasalessnapshotdef create_snapdeal_order(t_snapdeal_order):snapdealOrder = SnapdealOrder()snapdealOrder.orderId = t_snapdeal_order.orderIdsnapdealOrder.subOrderId = t_snapdeal_order.subOrderIdsnapdealOrder.referenceCode = t_snapdeal_order.referenceCodesnapdealOrder.productName = t_snapdeal_order.productNamesnapdealOrder.listingPrice = t_snapdeal_order.listingPricesnapdealOrder.snapdealTxnDate = to_py_date(t_snapdeal_order.snapdealTxnDate)snapdealOrder.maxNlc = t_snapdeal_order.maxNlcorder = Order.get_by(id=t_snapdeal_order.orderId)order.status = OrderStatus.ACCEPTEDuser = Nonetry:user_client = UserClient().get_client()user_to_add = User()user_to_add.email = 'SD.'+ str(t_snapdeal_order.orderId) + '@mailinator.com'user_to_add.password = 'hSp5gvCsrrhZcceE6mzzOQ'user_to_add.communicationEmail = user_to_add.emailuser_to_add.sourceStartTime = int(round(time.time() * 1000))user_to_add.sourceId = OrderSource.SNAPDEALuser_to_add.sex = Sex.WONT_SAYuser_to_add = user_client.createUser(user_to_add)user = user_to_addexcept:passif user:order.customer_id = user.userIdorder.customer_email = user.emailsession.commit()def get_snapdeal_order(order_id, reference_code, subOrder_id):query = SnapdealOrder.queryif order_id:query = query.filter(SnapdealOrder.orderId == order_id)elif reference_code==subOrder_id:if reference_code is None:reference_code=''query = query.filter(or_(SnapdealOrder.referenceCode == reference_code, SnapdealOrder.subOrderId== subOrder_id))else:query = query.filter(and_(SnapdealOrder.referenceCode == reference_code, SnapdealOrder.subOrderId== subOrder_id))return query.one()return query.all()def snapdeal_order_exists(suborder_id, reference_code):exists = SnapdealOrder.query.filter_by(subOrderId=suborder_id,referenceCode=reference_code).first()if exists is not None:return Trueelse:return Falsedef get_amazon_fba_sales_latest_snapshot_for_item(item_id):return AmazonFbaSalesSnapshot.query.filter(AmazonFbaSalesSnapshot.item_id==item_id).filter(AmazonFbaSalesSnapshot.dateOfSale!=datetime.datetime.now().date()).order_by(desc(AmazonFbaSalesSnapshot.dateOfSale)).first()def update_latest_fba_prices_for_item(fbaitemprices):fbasalessnapshot = AmazonFbaSalesSnapshot.query.filter(AmazonFbaSalesSnapshot.item_id==fbaitemprices.item_id).order_by(desc(AmazonFbaSalesSnapshot.dateOfSale)).first()if(fbasalessnapshot.ourPriceSnapshotDate < to_java_date(fbaitemprices.ourPriceSnapshotDate) and fbaitemprices.ourPrice is not None):fbasalessnapshot.ourPriceSnapshotDate = to_py_date(fbaitemprices.ourPriceSnapshotDate)fbasalessnapshot.ourPrice = fbaitemprices.ourPriceif(fbasalessnapshot.salePriceSnapshotDate < to_java_date(fbaitemprices.salePriceSnapshotDate) and fbaitemprices.salePrice is not None):fbasalessnapshot.salePriceSnapshotDate = to_py_date(fbaitemprices.salePriceSnapshotDate)fbasalessnapshot.salePrice = fbaitemprices.salePriceif(fbasalessnapshot.minFbaPriceSnapshotDate < to_java_date(fbaitemprices.minFbaPriceSnapshotDate) and fbaitemprices.minFbaPrice is not None):fbasalessnapshot.minFbaPriceSnapshotDate = to_py_date(fbaitemprices.minFbaPriceSnapshotDate)fbasalessnapshot.minFbaPrice = fbaitemprices.minFbaPriceif(fbasalessnapshot.minMfnPriceSnapshotDate < to_java_date(fbaitemprices.minMfnPriceSnapshotDate) and fbaitemprices.minMfnPrice is not None):fbasalessnapshot.minMfnPriceSnapshotDate = to_py_date(fbaitemprices.minMfnPriceSnapshotDate)fbasalessnapshot.minMfnPrice = fbaitemprices.minMfnPricesession.commit()def flipkart_order_exists(orderid,suborderid):exists = FlipkartOrder.query.filter_by(flipkartOrderId=orderid,flipkartSubOrderId=suborderid).first()if exists is not None:return Trueelse:return Falsedef create_flipkart_order(flipkartorder):order = FlipkartOrder()order.orderId = flipkartorder.orderIdorder.flipkartSubOrderId = flipkartorder.flipkartSubOrderIdorder.flipkartOrderId = flipkartorder.flipkartOrderIdorder.flipkartTxnDate = to_py_date(flipkartorder.flipkartTxnDate)order.shippingPrice = flipkartorder.shippingPriceorder.octroiFee = flipkartorder.octroiFeeorder.emiFee = flipkartorder.emiFeeorder.maxNlc = flipkartorder.maxNlcs_order = Order.get_by(id=flipkartorder.orderId)if s_order.cod:s_order.status = OrderStatus.COD_VERIFICATION_PENDINGelse:s_order.status = OrderStatus.ACCEPTEDs_order.accepted_timetsmap = datetime.datetime.now()user = Nonetry:user_client = UserClient().get_client()user_to_add = User()user_to_add.email = 'FK.'+ str(flipkartorder.orderId) + '@mailinator.com'user_to_add.password = 'gR9zF-Ish2im6tbYFNivgA'user_to_add.communicationEmail = user_to_add.emailuser_to_add.sourceStartTime = int(round(time.time() * 1000))user_to_add.sourceId = OrderSource.FLIPKARTuser_to_add.sex = Sex.WONT_SAYuser_to_add = user_client.createUser(user_to_add)user = user_to_addexcept:passif user:s_order.customer_id = user.userIds_order.customer_email = user.emailsession.commit()def get_flipkart_order(orderid):flipkartorder = FlipkartOrder.query.filter_by(orderId=orderid).first()if not flipkartorder:print "No found order for orderid " + str(orderid)raise TransactionServiceException(108, "no such order")return flipkartorderdef get_flipkart_order_by_subOrderId(flipkartOrderItemId):flipkartorder = FlipkartOrder.query.filter_by(flipkartSubOrderId=flipkartOrderItemId).first()if not flipkartorder:raise TransactionServiceException(108, "no such flipkart order " + str(flipkartOrderItemId))return flipkartorderdef update_flipkart_order_dates_and_awb(orderid,suborderid,date,awb):flipkartorder = FlipkartOrder.query.filter_by(flipkartOrderId=orderid,flipkartSubOrderId=suborderid).first()print flipkartorderorder = get_order(flipkartorder.orderId)if not order:print "No found order for orderid " + str(orderid)raise TransactionServiceException(108, "no such order")order.tracking_id = awborder.expected_delivery_time = to_py_date(date + 4*24*60*60*1000)order.promised_delivery_time = to_py_date(date + 4*24*60*60*1000)order.expected_shipping_time = to_py_date(date)order.promised_shipping_time = to_py_date(date)session.commit()def get_order_for_airwayBillNo(airwaybillNo):orders = Order.query.filter(Order.airwaybill_no==airwaybillNo).filter(Order.logisticsTransactionId != None).all()if not orders:orders = []return ordersdef get_orders_count_created_after_timestamp_for_source(timestamp,source):item_ordercount = dict()status=[15,18,34,0,1]items =session.query(LineItem.item_id,func.count(LineItem.id)).join((Order,LineItem.order_id==Order.id)).filter(Order.source==source).filter(Order.created_timestamp >=to_py_date(timestamp)).filter(not_(Order.status.in_(status))).group_by(LineItem.item_id).all()print itemsfor item in items:print item[0]print item[1]item_ordercount[item[0]] = item[1]return item_ordercountdef get_min_created_timestamp_undelivered_orders_for_source(source):order = order = Order.query.filter(Order.source== source).filter(Order.delivery_timestamp == None).filter(Order.status == OrderStatus.SHIPPED_FROM_WH).limit(1).one()print to_java_date(order.created_timestamp)return to_java_date(order.created_timestamp)def is_private_deal_transaction(transaction_id):result = Falsetransaction = Transaction.get_by(id=transaction_id)if transaction:allItems = []for order in transaction.orders:allItems.append(order.lineitems[0].item_id)catalog_client = CatalogClient().get_client()return len(catalog_client.getAllActivePrivateDeals(allItems, 0)) > 0return resultdef update_snapdeal_orders_status(orders):for statusString, orderList in orders.iteritems():if statusString == "Cancelled":try:for cancel_order in orderList:ref_code = cancel_order[0]sub_order_code = cancel_order[1]snapdeal_order = Nonetry:snapdeal_order = get_snapdeal_order(None, ref_code, sub_order_code)except Exception as e:print 'Caught in Updation of Cancelled Orders Getting Snapdeal Order'passif snapdeal_order:order = get_order(snapdeal_order.orderId)if order.status == OrderStatus.SHIPPED_FROM_WH:order.status = OrderStatus.SHIPPED_TO_LOGSTsession.commit()except Exception as e:print 'Caught in Updation of Cancelled Orders'print eprint sys.exc_info()if statusString == "Delivered":try:for del_order in orderList:ref_code = del_order[0]sub_order_code = del_order[1]dlvry_timestamp = del_order[2]snapdeal_order = Nonetry:snapdeal_order = get_snapdeal_order(None, ref_code, sub_order_code)except Exception as e:print 'Caught in Updation of Delivered Orders Getting Snapdeal Order'passif snapdeal_order:order = get_order(snapdeal_order.orderId)if order.status == OrderStatus.SHIPPED_FROM_WH:order.delivery_timestamp = datetime.datetime.strptime(dlvry_timestamp, "%Y-%m-%d %H:%M:%S")order.receiver = order.customer_nameorder.status = OrderStatus.DELIVERY_SUCCESSorder.statusDescription = "Order delivered"session.commit()except Exception as e:print 'Caught in Updation of Delivered Orders'print eprint sys.exc_info()'''try:for del_order in delivered_orders:ref_code = del_order[0]sub_order_code = del_order[1]dlvry_timestamp = del_order[2]if snapdeal_order_exists(sub_order_code, ref_code):snapdeal_order = get_snapdeal_order(None, None, sub_order_code)if snapdeal_order:order = get_order(snapdeal_order.orderId)if order.status == OrderStatus.SHIPPED_FROM_WH:order.delivery_timestamp = datetime.datetime.strptime(dlvry_timestamp, "%Y-%m-%d %H:%M:%S")order.receiver = order.customer_nameorder.status = OrderStatus.DELIVERY_SUCCESSorder.statusDescription = "Order delivered"session.commit()except Exception as e:print eprint sys.exc_info()'''def update_flipkart_orders_status(delivered_orders):try:for del_order in delivered_orders:flipkart_order_id = del_order[0]sub_order_code = del_order[1]dlvry_timestamp = del_order[2]if flipkart_order_exists(flipkart_order_id,sub_order_code):flipkart_order = get_flipkart_order_by_subOrderId(sub_order_code)if flipkart_order:order = get_order(flipkart_order.orderId)if order.status == OrderStatus.SHIPPED_FROM_WH:order.delivery_timestamp = datetime.datetime.strptime(dlvry_timestamp, "%Y-%m-%d %H:%M:%S")order.receiver = order.customer_nameorder.status = OrderStatus.DELIVERY_SUCCESSorder.statusDescription = "Order delivered"session.commit()except Exception as e:print eprint sys.exc_info()'''order_ids = delivered_orders.keys()for orderId in order_ids:order = Order.query.filter(Order.id == orderId).first()order.status = OrderStatus.DELIVERY_SUCCESSorder.statusDescription = "Order delivered"order.delivery_timestamp = datetime.datetime.strptime(delivered_orders.get(orderId), "%Y-%m-%d %H:%M:%S")session.commit()'''def bulk_add_or_update_amazon_fba_sales_snapshot(amazonfbasalessnapshotlist):for amazonfbasalessnapshot in amazonfbasalessnapshotlist:salesnapshotfordate = AmazonFbaSalesSnapshot.get_by(item_id = amazonfbasalessnapshot.item_id,dateOfSale=to_py_date(amazonfbasalessnapshot.dateOfSale).date(),fcLocation=amazonfbasalessnapshot.fcLocation)if salesnapshotfordate is None:amazon_fba_sales_snapshot = AmazonFbaSalesSnapshot()amazon_fba_sales_snapshot.dateOfSale = to_py_date(amazonfbasalessnapshot.dateOfSale).date()amazon_fba_sales_snapshot.item_id = amazonfbasalessnapshot.item_idamazon_fba_sales_snapshot.totalOrderCount = amazonfbasalessnapshot.totalOrderCountamazon_fba_sales_snapshot.amazonFbaInventory = amazonfbasalessnapshot.amazonFbaInventoryamazon_fba_sales_snapshot.isOutOfStock = amazonfbasalessnapshot.isOutOfStockamazon_fba_sales_snapshot.promotionOrderCount = amazonfbasalessnapshot.promotionOrderCountamazon_fba_sales_snapshot.totalSale = amazonfbasalessnapshot.totalSaleamazon_fba_sales_snapshot.promotionSale = amazonfbasalessnapshot.promotionSale#if amazonfbasalessnapshot.ourPrice is not None:amazon_fba_sales_snapshot.ourPriceSnapshotDate = to_py_date(amazonfbasalessnapshot.ourPriceSnapshotDate)amazon_fba_sales_snapshot.ourPrice = amazonfbasalessnapshot.ourPrice#if amazonfbasalessnapshot.salePrice is not None:amazon_fba_sales_snapshot.salePriceSnapshotDate = to_py_date(amazonfbasalessnapshot.salePriceSnapshotDate)amazon_fba_sales_snapshot.salePrice = amazonfbasalessnapshot.salePrice#if amazonfbasalessnapshot.minFbaPrice is not None:amazon_fba_sales_snapshot.minFbaPriceSnapshotDate = to_py_date(amazonfbasalessnapshot.minFbaPriceSnapshotDate)amazon_fba_sales_snapshot.minFbaPrice = amazonfbasalessnapshot.minFbaPrice#if amazonfbasalessnapshot.minMfnPrice is not None:amazon_fba_sales_snapshot.minMfnPriceSnapshotDate = to_py_date(amazonfbasalessnapshot.minMfnPriceSnapshotDate)amazon_fba_sales_snapshot.minMfnPrice = amazonfbasalessnapshot.minMfnPriceamazon_fba_sales_snapshot.fcLocation = amazonfbasalessnapshot.fcLocationelse:if(amazonfbasalessnapshot.totalOrderCount > 0):salesnapshotfordate.isOutOfStock = 0salesnapshotfordate.promotionOrderCount = amazonfbasalessnapshot.promotionOrderCountsalesnapshotfordate.totalSale = amazonfbasalessnapshot.totalSalesalesnapshotfordate.promotionSale = amazonfbasalessnapshot.promotionSalesalesnapshotfordate.totalOrderCount = amazonfbasalessnapshot.totalOrderCountsalesnapshotfordate.fcLocation = amazonfbasalessnapshot.fcLocationsession.commit()def get_created_orders_for_flipkart(flipkartorderids):item_ordercount = dict()orders = []flipkart_orders = session.query(FlipkartOrder).filter(FlipkartOrder.flipkartOrderId.in_(tuple(flipkartorderids))).all()print flipkart_ordersif len(flipkart_orders)!=0:for order in flipkart_orders:print order.orderIdorders.append(order.orderId)items =session.query(LineItem.item_id,func.count(LineItem.quantity)).join((Order,LineItem.order_id==Order.id)).filter(Order.id.in_(tuple(orders))).filter(Order.status >=3).filter(Order.shipping_timestamp==None).group_by(LineItem.item_id).all()else:return item_ordercountprint "items map after query"print itemsfor item in items:print "item id"print item[0]print "order count"print item[1]item_ordercount[item[0]] = item[1]print item_ordercountreturn item_ordercountdef change_easyship_mfn_order_txn_status(transaction_id, new_status, description, pickUp, orderType, source, shipTimestamp, deliveryTimeStamp):transaction = get_transaction(transaction_id)transaction.status = new_statustransaction.status_message = description## Assign runner in case of delhi pincodesif transaction.orders[0].pickupStoreId:logistics_client = LogisticsClient().get_client()store = logistics_client.getPickupStore(transaction.orders[0].pickupStoreId)if delhi_pincodes.__contains__(store.pin):pickUp = PickUpType.RUNNERif new_status == TransactionStatus.FAILED:for order in transaction.orders:order.status = OrderStatus.PAYMENT_FAILEDorder.statusDescription = "Payment Failed"elif new_status == TransactionStatus.AUTHORIZED or new_status == TransactionStatus.FLAGGED:for order in transaction.orders:if new_status == TransactionStatus.AUTHORIZED:order.status = OrderStatus.SUBMITTED_FOR_PROCESSINGorder.statusDescription = "Submitted to warehouse"elif new_status == TransactionStatus.FLAGGED:order.status = OrderStatus.PAYMENT_FLAGGEDorder.statusDescription = "Payment flagged by gateway"order.cod = Falseorder.orderType = orderType#After we got payment success, we will set logistics info alsologistics_client = LogisticsClient().get_client()#FIXME line item is only one now. If multiple will come, need to fix.item_id = order.lineitems[0].item_idlogistics_info = logistics_client.getLogisticsInfo(order.customer_pincode, item_id, DeliveryType.PREPAID, pickUp)#current_time = datetime.datetime.now()#logistics_info.deliveryTime = adjust_delivery_time(to_py_date(deliveryTimeStamp), 0)#logistics_info.shippingTime = adjust_delivery_time(to_py_date(shipTimestamp), 0)#logistics_info.deliveryDelay = 0order.otg = logistics_info.otgAvailableorder.warehouse_id = logistics_info.warehouseIdorder.fulfilmentWarehouseId = logistics_info.fulfilmentWarehouseIdorder.logistics_provider_id = 45#Start:- Added by Manish Sharma for FedEx Integration - Shipment Creation on 31-Jul-2013#order.airwaybill_no = logistics_info.airway_billno#order.tracking_id = order.airwaybill_no#End:- Added by Manish Sharma for FedEx Integration- Shipment Creation on 31-Jul-2013order.courier_delivery_time = to_py_date(deliveryTimeStamp).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)order.expected_shipping_time = to_py_date(shipTimestamp).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)order.promised_shipping_time = order.expected_shipping_timeorder.expected_delivery_time = to_py_date(deliveryTimeStamp).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)order.promised_delivery_time = order.expected_delivery_timeif order.pickupStoreId:order.otg = Falseinventory_client = InventoryClient().get_client()if order.productCondition != ProductCondition.BAD:inventory_client.reserveItemInWarehouse(item_id, logistics_info.fulfilmentWarehouseId, sourceId, order.id, to_java_date(order.created_timestamp), to_java_date(order.promised_shipping_time), order.lineitems[0].quantity)try:item_pricing = inventory_client.getItemPricing(item_id, -1)order.lineitems[0].transfer_price = item_pricing.transferPriceorder.lineitems[0].nlc = item_pricing.nlcexcept:print "Not able to get transfer price. Skipping"catalog_client = CatalogClient().get_client()voucherAmount = catalog_client.getVoucherAmount(item_id, VoucherType.SPICEDECK_MOBILE)if voucherAmount:__create_recharge_voucher_tracker(order, voucherAmount, VoucherType.SPICEDECK_MOBILE)#Note 2 Buy back Offerif item_id in (7974, 7558) and transaction.coupon_code is not None and transaction.coupon_code.lower() == "note2buyback":order.status = OrderStatus.COD_VERIFICATION_PENDINGorder.statusDescription = "Note 2 Buy Back Offer - Approval Pending from CRM Team"order.otg = Falseelif new_status == TransactionStatus.COD_IN_PROCESS:for order in transaction.orders:order.status = OrderStatus.COD_VERIFICATION_PENDINGorder.statusDescription = "Verification Pending"order.cod = Trueorder.orderType = orderType#After we got payment success, we will set logistics info alsologistics_client = LogisticsClient().get_client()#FIXME line item is only one now. If multiple will come, need to fix.item_id = order.lineitems[0].item_idif order.pickupStoreId:# Need to send prepaid awb number for store pick up orderslogistics_info = logistics_client.getLogisticsEstimation(item_id, order.customer_pincode, DeliveryType.COD)#//Start:- Added by Manish Sharma for FedEx Integration- Shipment Creation on 31-Jul-2013#prepaid_logistics_info = logistics_client.getLogisticsInfo(order.customer_pincode, item_id, DeliveryType.PREPAID, pickUp)#logistics_info.airway_billno = prepaid_logistics_info.airway_billno#logistics_info.providerId = prepaid_logistics_info.providerId#End:- Added by Manish Sharma for FedEx Integration- Shipment Creation on 31-Jul-2013# Will not provide OTG in pickup storeorder.otg = Falseelse:logistics_info = logistics_client.getLogisticsInfo(order.customer_pincode, item_id, DeliveryType.COD, pickUp)order.otg = logistics_info.otgAvailable#current_time = datetime.datetime.now()#logistics_info.deliveryTime = adjust_delivery_time(current_time, logistics_info.deliveryTime)#logistics_info.shippingTime = adjust_delivery_time(current_time, logistics_info.shippingTime)#logistics_info.deliveryDelay = adjust_delivery_time(current_time, (logistics_info.shippingTime+logistics_info.deliveryDelay))order.warehouse_id = logistics_info.warehouseIdorder.fulfilmentWarehouseId = logistics_info.fulfilmentWarehouseIdorder.logistics_provider_id = 45#Start:- Added by Manish Sharma for FedEx Integration- Shipment Creation on 31-Jul-2013#order.airwaybill_no = logistics_info.airway_billno#order.tracking_id = order.airwaybill_no#End:- Added by Manish Sharma for FedEx Integration- Shipment Creation on 31-Jul-2013order.courier_delivery_time = to_py_date(deliveryTimeStamp).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)order.expected_shipping_time = to_py_date(shipTimestamp).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)order.promised_shipping_time = order.expected_shipping_timeorder.expected_delivery_time = to_py_date(deliveryTimeStamp).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)order.promised_delivery_time = order.expected_delivery_timeinventory_client = InventoryClient().get_client()if order.productCondition != ProductCondition.BAD:inventory_client.reserveItemInWarehouse(item_id, logistics_info.fulfilmentWarehouseId, sourceId, order.id, to_java_date(order.created_timestamp), to_java_date(order.promised_shipping_time), order.lineitems[0].quantity)try:item_pricing = inventory_client.getItemPricing(item_id, -1)order.lineitems[0].transfer_price = item_pricing.transferPriceorder.lineitems[0].nlc = item_pricing.nlcexcept:print "Not able to get transfer price. Skipping"catalog_client = CatalogClient().get_client()voucherAmount = catalog_client.getVoucherAmount(item_id, VoucherType.SPICEDECK_MOBILE)if voucherAmount:__create_recharge_voucher_tracker(order, voucherAmount, VoucherType.SPICEDECK_MOBILE)session.commit()if new_status in (TransactionStatus.AUTHORIZED, TransactionStatus.FLAGGED, TransactionStatus.COD_IN_PROCESS):try:if order.source == OrderSource.WEBSITE:if new_status == TransactionStatus.COD_IN_PROCESS:transaction_requiring_extra_processing = TransactionRequiringExtraProcessing()transaction_requiring_extra_processing.category = 'COD_VERIFICATION'transaction_requiring_extra_processing.transaction_id = transaction_idsession.commit()elif new_status == TransactionStatus.FLAGGED:transaction_requiring_extra_processing = TransactionRequiringExtraProcessing()transaction_requiring_extra_processing.category = 'PAYMENT_FLAGGED'transaction_requiring_extra_processing.transaction_id = transaction_idsession.commit()elif order.source == OrderSource.STORE:order.otg = Falsesession.commit()catalog_client = CatalogClient().get_client()sourcePricing = catalog_client.getStorePricing(order.lineitems[0].item_id)if order.total_amount >= sourcePricing.minPrice:order.status = OrderStatus.SUBMITTED_FOR_PROCESSINGorder.statusDescription = "Order Accepted"session.commit()sod = StoreOrderDetail.get_by(orderId = order.id)__push_store_collection_to_hotspot(order, "advance", sod.cashAmount, sod.cardAmount)else:order.status = OrderStatus.COD_VERIFICATION_PENDINGorder.statusDescription = "Approval Pending"content = "<html><body>"content += "<h4>Order Id: " + str(order.id) + "</h4>"content += "<h4>Product: " + str(order.lineitems[0]) + "</h4>"content += "<h4>Min Price: " + str(sourcePricing.minPrice) + "</h4>"content += "<h4>Recommended Price: " + str(sourcePricing.recommendedPrice) + "</h4>"content += "<h2>Approval Requested for Price: " + str(order.total_amount) + "</h2>"content += "<h2>Note 1: If this discount price is approved then reply 'Approved' otherwise 'Not Approved' without changing anythig in the Mail.</h2>"content += "<h2>Note 2: For Quick approval using browser <a href='http://support.shop2020.in:8080/Support/price-approval?xszbg=" + base64.b64encode(str(order.id)) + "'>Click Here</a></h2>"content += "<br><br></body></html>"store = get_hotspot_store(order.storeId, "")helper_client = HelperClient().get_client()helper_client.saveUserEmailForSending(store.approvalEmail.split(';'), SaholicHelpEmailId, "Price approval requested for " + str(order.lineitems[0]) + " order Id " + str(order.id) + " in store " + store.hotspotId , content, str(transaction_id), "PriceApproval", [], [], order.source)session.commit()else:order.otg = Falsesession.commit()except Exception as e:print "Error inserting transaction Id: " + str(transaction_id) + " due to " + str(e)return Truedef update_amazon_fba_order_returns(fbaOrderReturns):for order_return in fbaOrderReturns:orderReturn = AmazonFbaOrderReturns.query.filter(AmazonFbaOrderReturns.amazonOrderId==order_return.amazonOrderId).filter(AmazonFbaOrderReturns.insertionTimestamp == to_py_date(order_return.insertionTimestamp)).filter(AmazonFbaOrderReturns.sku==order_return.sku).first()if orderReturn:orderReturn.sellableReturnQuantity = order_return.sellableReturnQuantityorderReturn.nonSellableReturnQuantity = order_return.nonSellableReturnQuantitysession.commit()else:orderReturn = AmazonFbaOrderReturns()orderReturn.amazonOrderId = order_return.amazonOrderIdorderReturn.insertionTimestamp = to_py_date(order_return.insertionTimestamp)orderReturn.sku = order_return.skuorderReturn.creationTimestamp = to_py_date(order_return.creationTimestamp)orderReturn.shippedQuantity = order_return.shippedQuantityorderReturn.sellableReturnQuantity = order_return.sellableReturnQuantityorderReturn.nonSellableReturnQuantity = order_return.nonSellableReturnQuantitysession.commit()def get_all_amazon_fba_order_returns(insertionTimestamp):returns = AmazonFbaOrderReturns.query.filter(AmazonFbaOrderReturns.insertionTimestamp==to_py_date(insertionTimestamp)).all()if not returns:returns = []return returnsdef get_total_sale_returns_fba_skus_curent_time(insertionTimestamp):allFbaSkuDetails = session.query(AmazonFbaOrderReturns.sku, func.sum(AmazonFbaOrderReturns.shippedQuantity), func.sum(AmazonFbaOrderReturns.sellableReturnQuantity), func.sum(AmazonFbaOrderReturns.nonSellableReturnQuantity)).group_by(AmazonFbaOrderReturns.sku).filter(AmazonFbaOrderReturns.insertionTimestamp == to_py_date(insertionTimestamp)).all()returnAllFbaSkuDetails = {}for fbaSkuDetail in allFbaSkuDetails:saleReturnDetail = {}saleReturnDetail['Sale'] = fbaSkuDetail[1]saleReturnDetail['SaleableReturn'] = fbaSkuDetail[2]saleReturnDetail['NonSaleableReturn'] = fbaSkuDetail[3]returnAllFbaSkuDetails[fbaSkuDetail[0]]= saleReturnDetailreturn returnAllFbaSkuDetailsdef get_amazon_fba_sales_latest_snapshot_for_item_location_wise(item_id,location):return AmazonFbaSalesSnapshot.query.filter(AmazonFbaSalesSnapshot.item_id==item_id).filter(AmazonFbaSalesSnapshot.fcLocation==location).filter(AmazonFbaSalesSnapshot.dateOfSale!=datetime.datetime.now().date()).order_by(desc(AmazonFbaSalesSnapshot.dateOfSale)).first()def get_verification_pending_orders_fk():retOrders = Order.query.filter(Order.source==OrderSource.FLIPKART).filter(Order.status==OrderStatus.COD_VERIFICATION_PENDING).all()retFkOrders = []order_ids = []if not retOrders:return retFkOrderselse:for order in retOrders:order_ids.append(order.id)retFkOrders = FlipkartOrder.query.filter(FlipkartOrder.orderId.in_(tuple(order_ids)))if not retFkOrders:retFkOrders = []return retFkOrdersdef add_invoice_details_to_orders(transactionId, customerId):orders = Order.query.filter_by(transaction_id=transactionId, customer_id=customerId).all()if not orders:raise TransactionServiceException(101, "No order for the transaction Unable to Print Invoice")else:invoiceNo = get_next_invoice_number(orders[0].orderType)for order in orders:order.invoice_number = invoiceNosession.commit()def get_fa_order_by_fk_order_id(fk_OrderId,fk_OrderItemId):faOrder = FlipkartAdvantageOrder.query.filter_by(fkOrderId=fk_OrderId,fkOrderItemId=fk_OrderItemId).first()if not faOrder:print "Not found order for orderId " + str(fk_OrderId)raise TransactionServiceException(108, "no such order")return faOrderdef flipkart_fa_order_exists(fk_OrderId,fk_OrderItemId):faOrder = FlipkartAdvantageOrder.query.filter_by(fkOrderId=fk_OrderId,fkOrderItemId=fk_OrderItemId).first()if not faOrder:return Falseelse:return Truedef get_all_fa_orders_list(status):faOrders = Noneif status == 'all':faOrders = FlipkartAdvantageOrder.query.all()else:faOrders = FlipkartAdvantageOrder.query.filter(FlipkartAdvantageOrder.status==status).all()if not faOrders:faOrders = []return faOrdersdef add_update_fa_orders_bulk(faOrdersList):for faOrder in faOrdersList:if faOrder.status == 'approved':fa_Order = FlipkartAdvantageOrder()fa_Order.fkOrderId = faOrder.fkOrderIdfa_Order.fkOrderItemId = faOrder.fkOrderItemIdfa_Order.sku = faOrder.skufa_Order.creationTimestamp = to_py_date(faOrder.creationTimestamp)fa_Order.customerName = faOrder.customerNamefa_Order.customerAddress = faOrder.customerAddressfa_Order.pincode = faOrder.pincodefa_Order.customerCity = faOrder.customerCityfa_Order.customerState = faOrder.customerStatefa_Order.customerPhone = faOrder.customerPhonefa_Order.status = faOrder.statusfa_Order.quantity = faOrder.quantityfa_Order.totalPrice = faOrder.totalPricefa_Order.listPrice = faOrder.listPricefa_Order.modifiedDate = to_py_date(faOrder.modifiedDate)fa_Order.listingId = faOrder.listingIdfa_Order.cancelReason = faOrder.cancelReasonfa_Order.returnReason = faOrder.returnReasonfa_Order.freebieItemId = faOrder.freebieItemIdfa_Order.productTitle = faOrder.productTitleelse:fa_Order = FlipkartAdvantageOrder.query.filter_by(fkOrderId=faOrder.fkOrderId,fkOrderItemId=faOrder.fkOrderItemId).first()if fa_Order:if fa_Order.status !=faOrder.status:fa_Order.status = faOrder.statusfa_Order.cancelReason = faOrder.cancelReasonfa_Order.returnReason = faOrder.returnReasonfa_Order.modifiedDate = to_py_date(faOrder.modifiedDate)else:fa_Order = FlipkartAdvantageOrder()fa_Order.fkOrderId = faOrder.fkOrderIdfa_Order.fkOrderItemId = faOrder.fkOrderItemIdfa_Order.sku = faOrder.skufa_Order.creationTimestamp = to_py_date(faOrder.creationTimestamp)fa_Order.customerName = faOrder.customerNamefa_Order.customerAddress = faOrder.customerAddressfa_Order.pincode = faOrder.pincodefa_Order.customerCity = faOrder.customerCityfa_Order.customerState = faOrder.customerStatefa_Order.customerPhone = faOrder.customerPhonefa_Order.status = faOrder.statusfa_Order.quantity = faOrder.quantityfa_Order.totalPrice = faOrder.totalPricefa_Order.listPrice = faOrder.listPricefa_Order.modifiedDate = to_py_date(faOrder.modifiedDate)fa_Order.listingId = faOrder.listingIdfa_Order.cancelReason = faOrder.cancelReasonfa_Order.returnReason = faOrder.returnReasonfa_Order.freebieItemId = faOrder.freebieItemIdfa_Order.productTitle = faOrder.productTitlesession.commit()def get_recharge_order_status(rechargeOrderId, final):d_rechargeOrder = get_recharge_order(rechargeOrderId)if d_rechargeOrder.status == RechargeOrderStatus.RECHARGE_UNKNOWN:try:status, description = RechargeService.checkTransactionStatus('', str(rechargeOrderId))print status, descriptionif status:update_recharge_order_status(rechargeOrderId, RechargeOrderStatus.RECHARGE_SUCCESSFUL)else:update_recharge_order_status(rechargeOrderId, RechargeOrderStatus.RECHARGE_FAILED)except:if final:d_rechargeOrder.status = RechargeOrderStatus.PAYMENT_SUCCESSFULd_rechargeOrder.responseTimestamp = datetime.datetime.now()session.commit()finally:return get_recharge_order(rechargeOrderId)else:return d_rechargeOrderdef get_recharge_transaction_status(rechargeTransactionId, final):d_rechargeTransaction = get_recharge_transaction(rechargeTransactionId)if d_rechargeTransaction.status == RechargeOrderStatus.RECHARGE_IN_PROCESS:try:status, description = RechargeService.checkTransactionStatus('', str(rechargeTransactionId))d_rechargeTransaction.description = descriptionprint status, descriptionif status:update_recharge_transaction_status(rechargeTransactionId, RechargeOrderStatus.RECHARGE_SUCCESSFUL)else:update_recharge_transaction_status(rechargeTransactionId, RechargeOrderStatus.RECHARGE_FAILED)except:if final:d_rechargeTransaction.status = RechargeOrderStatus.RECHARGE_UNKNOWNd_rechargeTransaction.responseTime = datetime.datetime.now()session.commit()finally:return get_recharge_transaction(rechargeTransactionId)else:return d_rechargeTransactiondef accept_package_orders(orders):totalWeight = 0.0totalOrdersAmount = 0.0ordersList = get_order_list(orders)totalOrderQuantity = 0for orderObj in ordersList:totalOrderQuantity = totalOrderQuantity + long(orderObj.lineitems[0].quantity)print ordersupdatedOrders = logisticsProviderFinalCheck(ordersList)user_client = UserClient().get_client()isPrivateDealUser = user_client.isPrivateDealUser(updatedOrders[0].customer_id)privateDealUser = Noneif isPrivateDealUser:privateDealUser = user_client.getPrivateDealUser(updatedOrders[0].customer_id)logistics_client = LogisticsClient().get_client()provider = logistics_client.getProvider(updatedOrders[0].logistics_provider_id)providerLimits = logistics_client.getProviderLimitDetailsForPincode(provider.id, updatedOrders[0].customer_pincode)print 'Accpet Order Process Started''''Check For Pre Conditions'''for order in updatedOrders:if order.total_weight is None or order.total_weight ==0:raise TransactionServiceException(208, "Weight Value Not Defined for order:- "+ str(order.id)+". Contact Category Team.")totalWeight = totalWeight + order.total_weight#if order.cod:totalOrdersAmount = totalOrdersAmount + order.total_amountif order.cod:if isPrivateDealUser and privateDealUser.bulkShipmentAmountLimit:if totalOrdersAmount > privateDealUser.bulkShipmentAmountLimit:raise TransactionServiceException(208, "Private Deal Counter Group Shipment Amount Limit Violated i.e. "+ str(privateDealUser.bulkShipmentAmountLimit))else:if totalOrdersAmount > 50000:raise TransactionServiceException(208, "Private Deal Counter Group Shipment Amount Limit Violated i.e. "+ str(50000))if totalWeight > provider.bundleWeightLimit:raise TransactionServiceException(210, "Logistics Partner "+provider.name+ " Group Shipment Weight Limit Violated i.e. "+str(provider.bundleWeightLimit))if order.cod:if totalOrdersAmount > provider.maxCodLimit:raise TransactionServiceException(210, "Logistics Partner "+provider.name+ " Max Cod Amount Collection Limit Violated i.e. "+ str(provider.maxCodLimit))if order.logistics_provider_id not in [4, 48] :providerCodLimit = float(providerLimits.get("providerCodLimit"))providerPrepaidLimit = float(providerLimits.get("providerPrepaidLimit"))if order.cod:if totalOrdersAmount > providerCodLimit:raise TransactionServiceException(212, "Provider Maximum COD Limit Violated for Customer Pincode i.e. "+str(providerCodLimit))if not order.cod:if totalOrdersAmount > providerPrepaidLimit:raise TransactionServiceException(212, "Logistics Partner "+provider.name+ " Max Prepaid Amount Limit Violated Rs." +str(providerPrepaidLimit))for order in updatedOrders:if order.status in [OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.LOW_INV_PO_RAISED, OrderStatus.LOW_INV_REVERSAL_IN_PROCESS, OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT, OrderStatus.CAPTURE_IN_PROCESS]:if not order.cod:if order.transaction.status == TransactionStatus.AUTHORIZED and order.transaction.payment_option != capitalFloatPayMethod:__capture_txn(order.transaction_id)change_transaction_status(order.transaction_id, TransactionStatus.IN_PROCESS, "Payment received", PickUpType.COURIER, order.orderType, order.source)break''' Change IP using Config Client and Handle Exception '''try:inventoryDbHost = str(ConfigClient().get_property("inventory_service_db_hostname"))conn = getDbConnection(inventoryDbHost,"root", "shop2020", "inventory")except:raise TransactionServiceException(212, "Unable to connect to Inventory System")#conn = getDbConnection("localhost","root","shop2020","inventory")print 'Connected to Inventory DB'for order in updatedOrders:if order.status in [OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.LOW_INV_PO_RAISED, OrderStatus.LOW_INV_REVERSAL_IN_PROCESS, OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT, OrderStatus.CAPTURE_IN_PROCESS]:order.status = OrderStatus.ACCEPTEDorder.statusDescription = "Order Accepted"order.accepted_timestamp = datetime.datetime.now()if order.source == 6 or order.source == 7 or order.source == 8:if order.source == 8 and order.cod:order.cod = FalsecontinueitemId = order.lineitems[0].item_idselectSql = "select warehouse_id, availability, reserved, held from currentinventorysnapshot where item_id = %d"%(itemId)avalibilityResult = Nonetry:cursor = conn.cursor()cursor.execute(selectSql)avalibilityResult = cursor.fetchall()except Exception as e:print "Error: unable to fetch data"wrongFulFillmentWh = FalseitemAvailibility = ItemInventory()availability = {}reserved = {}held = {}if avalibilityResult is not None:for avalibilityRecord in avalibilityResult:if order.fulfilmentWarehouseId == avalibilityRecord[0]:wrongFulFillmentWh = Falsebreakelse:wrongFulFillmentWh = Trueavailability[avalibilityRecord[0]] = avalibilityRecord[1]reserved[avalibilityRecord[0]] = avalibilityRecord[2]held[avalibilityRecord[0]] = avalibilityRecord[3]continueitemAvailibility.id = itemIditemAvailibility.availability = availabilityitemAvailibility.reserved = reserveditemAvailibility.held = heldwarehousesResult = Noneif wrongFulFillmentWh:selectSql = "SELECT * from warehouse where warehouseType ='OURS' and inventoryType='GOOD' and billingWarehouseId=%d"%(order.warehouse_id)try:cursor = conn.cursor()cursor.execute(selectSql)warehousesResult = cursor.fetchall()except Exception as e:print "Error: unable to fetch data 1"newFulfillWh = Noneif warehousesResult is not None:for warehouse in warehousesResult:if itemAvailibility.availability.has_key(warehouse[0]) and itemAvailibility.availability[warehouse[0]] >= itemAvailibility.reserved[warehouse[0]] + order.lineitems[0].quantity:sql_update = "update currentinventorysnapshot set reserved = reserved -%d where item_id = %d and warehouse_id = %d"%(int(order.lineitems[0].quantity),itemId,order.fulfilmentWarehouseId)sql_delete = "delete from currentreservationsnapshot where order_id = %d and item_id = %d and warehouse_id = %d and source_id= %d"%(order.id,itemId,order.fulfilmentWarehouseId,sourceId)print sql_updatetry:cursor = conn.cursor()cursor.execute(sql_update)cursor.execute(sql_delete)except:conn.rollback()sql_get = "select * from currentinventorysnapshot where item_id=%d and warehouse_id=%d"%(itemId,warehouse[0])try:cursor = conn.cursor()cursor.execute(sql_get)invsnapshot = cursor.fetchone()if invsnapshot is not None:sql_update = "update currentinventorysnapshot set reserved = reserved +%d where item_id = %d and warehouse_id = %d"%(int(order.lineitems[0].quantity),itemId,warehouse[0])cursor.execute(sql_update)else:sql_insert = "insert into currentinventorysnapshot values(%d,%d,%d,%d,%d)"%(itemId,warehouse[0],0,int(order.lineitems[0].quantity),0)cursor.execute(sql_insert)sql_res_insert = "insert into currentreservationsnapshot values(%d,%d,%d,%d,'%s','%s',%d)"%(itemId,warehouse[0],sourceId,order.id,str(order.created_timestamp), str(order.promised_shipping_time), int(order.lineitems[0].quantity))cursor.execute(sql_res_insert)except:conn.rollback()order.fulfilmentWarehouseId = warehouse[0]newFulfillWh = warehouse[0]breakorderFulfillmentWarehouse = Nonetry:cursor = conn.cursor()if wrongFulFillmentWh:selectSql = "select id, displayName, vendor_id from warehouse where id = %d"%(newFulfillWh)print "SelectSql", selectSqlcursor.execute(selectSql)else:selectSql = "select id, displayName, vendor_id from warehouse where id = %d"%(order.fulfilmentWarehouseId)cursor.execute(selectSql)orderFulfillmentWarehouse = cursor.fetchone()except Exception as e:print "Error: unable to fetch data 2"if order.productCondition != ProductCondition.BAD:if orderFulfillmentWarehouse is not None:itemPricing = NoneselectSql = "select * from vendoritempricing where item_id = %d and vendor_id = %d"%(itemId,orderFulfillmentWarehouse[2])try:cursor = conn.cursor()cursor.execute(selectSql)itemPricing = cursor.fetchone()except Exception as e:print "Error: unable to fetch data 3"if itemPricing is None:raise TransactionServiceException(214, "Vendor Item Pricing Missing For Item Id "+str(itemId)+ " and Fulfillment Warehouse "+ str(orderFulfillmentWarehouse[1]))else:order.lineitems[0].transfer_price = itemPricing[4]order.lineitems[0].nlc = itemPricing[5]else:conn.close()raise TransactionServiceException(216, "Order in Unacceptable Status.. "+str(order.id))try:conn.commit()except:conn.close()conn.close()txnSeqRequired = 0txnShipSeq = TransactionShipmentSequence.query.filter(TransactionShipmentSequence.transactionId==updatedOrders[0].transaction_id).order_by(desc(TransactionShipmentSequence.id)).first()if txnShipSeq is None:txnShipSeq = TransactionShipmentSequence()txnShipSeq.transactionId = updatedOrders[0].transaction_idtxnShipSeq.createdTimestamp = datetime.datetime.now()txnShipSeq.sequence = 1txnSeqRequired = 1else:txnShipSeqNew = TransactionShipmentSequence()txnShipSeqNew.transactionId = txnShipSeq.transactionIdtxnShipSeqNew.createdTimestamp = datetime.datetime.now()txnShipSeqNew.sequence = txnShipSeq.sequence + 1txnSeqRequired = txnShipSeq.sequence + 1for order in updatedOrders:order.logisticsTransactionId = str(order.transaction_id)+"-"+str(txnSeqRequired)session.commit()return Truedef get_group_orders_by_logistics_txn_id(logisticsTxnId):orders = Order.query.filter(Order.logisticsTransactionId==logisticsTxnId).all()if not orders:orders = []return ordersdef add_billing_details_for_groupped_orders(orderIds, invoice_number, itemNumbersMap, serialNumbersMap, freebieWarehouseIdMap, billed_by, jacketNumber, billingType, authorize, invoiceType):# print 'orderIds',orderIds# print 'invoice_number', invoice_number# print 'itemNumbersMap', itemNumbersMap# print 'serialNumbersMap', serialNumbersMap# print 'freebieWarehouseIdMap', freebieWarehouseIdMap# print 'billed_by', billed_by# print 'jacketNumber', jacketNumber# print 'billingType', billingType# print 'authorize', authorize# print 'invoiceType', invoiceType''' Check for Biller'''if billed_by is None or billed_by.strip() == "":raise TransactionServiceException(110, "Invalid Biller")ordersList = []''' Check for Order'''for orderId in orderIds:order = Order.get_by(id=orderId)if not order:raise TransactionServiceException(301, "No order found for the given order id" + str(orderId))else:ordersList.append(order)singleOrder = ordersList[0]hsnCode = singleOrder.lineitems[0].hsnCodeif singleOrder.logisticsTransactionId is not None:grouppedOrders = get_group_orders_by_logistics_txn_id(singleOrder.logisticsTransactionId)errorString = ""missingString = "Billing Details Missing for following Orders:- "for ordObj in grouppedOrders:if ordObj.id not in orderIds and ordObj.status==OrderStatus.ACCEPTED :errorString = errorString + "Order Id:- " +str(ordObj.id) +" "if len(errorString)>0:raise TransactionServiceException(301, missingString + errorString)#inventoryDbConnection = getDbConnection("192.168.190.114","root", "shop2020", "inventory")try:warehouseDbConnection = getDbConnection("192.168.190.114","root", "shop2020", "warehouse")except:raise TransactionServiceException(302, "Unable to connect to Warehouse System")inventory_client = InventoryClient().get_client()warehouse_client = WarehouseClient().get_client()catalog_client = CatalogClient().get_client()lineItemSize = 0individualInvoice = Truewarehouse = inventory_client.getWarehouse(ordersList[0].warehouse_id)whState = fetchStateMaster().get(warehouse.stateId)taxType = __getOrderTaxType(ordersList[0], whState.stateName)if not catalog_client.isAlive():catalog_client = CatalogClient().get_client()itemIds = []for order in ordersList:itemIds.append(order.lineitems[0].item_id)if taxType == TaxType.IGST:gstRatesMap = catalog_client.getStateTaxRate(itemIds, -1)else:gstRatesMap = catalog_client.getStateTaxRate(itemIds, whState.id)orderscansMap = {}orderInventoryItemMap = {}orderFulfilmentWarehouseMap = {}nonSerializedUsedInventoryMap = {}for order in ordersList:scanList = []inventoryItemList = []order.taxType = taxTypeif jacketNumber is None or jacketNumber <= 0:if order.source == OrderSource.EBAY or order.source == OrderSource.SNAPDEAL or order.source == OrderSource.FLIPKART:print "Skipping Jacket Number field for OrderId " + str(orderId)else:raise TransactionServiceException(303, "Invalid jacket number")'''First checking whether freebie can be billed or not otherwise wont proceed.'''if order.freebieItemId:if billingType == BillingType.OURS or billingType == BillingType.OURS_EXTERNAL:freebieWarehouseId = freebieWarehouseIdMap.get(order.id)[0]if freebieWarehouseId:if not inventory_client.isAlive():inventory_client = InventoryClient().get_client()warehouse = inventory_client.getWarehouse(freebieWarehouseId)if warehouse.warehouseType!= WarehouseType.OURS or warehouse.inventoryType != InventoryType.GOOD:raise TransactionServiceException(304,'Billing of Freebie is only allowed from OURS_GOOD warehouses. Order Id:- '+str(order.id))if not warehouse_client.isAlive():warehouse_client = WarehouseClient().get_client()isItemAvailable = warehouse_client.isItemAvailableForSale(order.freebieItemId, "", freebieWarehouseId)if isItemAvailable == False:raise TransactionServiceException(305,'No Freebie Item available. Order Id- '+str(order.id))else:raise TransactionServiceException(306,'No warehouseId provided for billing of freebie. Order Id-'+str(order.id))lineitem = order.lineitems[0]item_id = lineitem.item_id'''Checking if order is a freebie split-order and if the order is cod and if the original order is marked as delivered.'''freebie_order_info_text = "Freebie Order for Order ID"if lineitem.extra_info and freebie_order_info_text in lineitem.extra_info:canbillOrder = __isFreebieOrderBillable(order)if canbillOrder == False:raise TransactionServiceException(307,'Parent order for this is COD and is still undelivered')if not catalog_client.isAlive():catalog_client = CatalogClient().get_client()item = catalog_client.getItem(item_id)if ItemType.SERIALIZED == item.type and lineitem.quantity>2:individualInvoice=Falseif order.orderType== OrderType.B2B:individualInvoice=FalselineItemSize = lineItemSize+1if order.status == OrderStatus.ACCEPTED:if order.source == 6:order.jacket_number = "600"+str(orderId)elif order.source == 7:order.jacket_number = "700"+str(orderId)elif order.source == 8:order.jacket_number = "800"+str(orderId)else:order.jacket_number = jacketNumberitemNumbers = itemNumbersMap.get(order.id)lineitem.item_number = itemNumbers[0]serialNumbers = serialNumbersMap.get(order.id)if serialNumbers:if lineitem.serial_number:serialNumbers.insert(0, lineitem.serial_number)#dupSerials = [ser for ser, count in collections.Counter(serialNumbers).items() if count > 1]dupSerials = set([x for x in serialNumbers if serialNumbers.count(x) > 1])if dupSerials:logging.info("*********Duplicates are being scanned***********\n" + ",".join(dupSerials))raise TransactionServiceException(110, 'Found repeated serialNumbers in: ' + ",".join(dupSerials))lineitem.serial_number = ','.join(serialNumbers)for serialNumber in serialNumbers:lineItemImei = Line_Item_Imei()lineItemImei.serial_number = serialNumberlineItemImei.line_item_id = lineitem.idorder.status = OrderStatus.BILLEDorder.statusDescription = "Order Billed"order.billing_timestamp = datetime.datetime.now()order.billed_by = billed_by# Letting the billing process fail in cases where we are unable to# fill in transfer pricetry:if not inventory_client.isAlive():inventory_client = InventoryClient().get_client()warehouse = inventory_client.getWarehouse(order.fulfilmentWarehouseId)if order.productCondition != ProductCondition.BAD:item_pricing = inventory_client.getItemPricing(item_id, warehouse.vendor.id)lineitem.transfer_price = item_pricing.transferPricelineitem.nlc = item_pricing.nlc#Now onwards vatRates are obsolete, we will be using fields igst, sgst and cgstgstRates = gstRatesMap.get(lineitem.item_id)lineitem.igstRate = gstRates.igstRatelineitem.cgstRate = gstRates.cgstRatelineitem.sgstRate = gstRates.sgstRateorder.vendorId = warehouse.vendor.idexcept InventoryServiceException as e:print sys.exc_info()[0]print e.messageif warehouseDbConnection.open:warehouseDbConnection.close()raise TransactionServiceException(110, 'Transfer price missing for itemId: ' + str(item_id) + ' and vendor: ' + str(warehouse.vendor.id))# if order.orderType == OrderType.B2B:# tinNumber = Attribute.query.filter(Attribute.orderId == order.id).filter(Attribute.name == "tinNumber").first()# if tinNumber is None:# if warehouseDbConnection.open:# warehouseDbConnection.close()# raise TransactionServiceException(308, "Tin Number is Missing for B2B Order. Please contact engineering Team" + str(orderId))# if newTaxType != 0:# order.orderType = OrderType.B2Cif billingType == BillingType.OURS:if order.productCondition == ProductCondition.GOOD:# Fetching GOOD w/h corresponding to the virtual one hereif not warehouse.billingWarehouseId:if not inventory_client.isAlive():inventory_client = InventoryClient().get_client()warehouse = inventory_client.getWarehouses(None, InventoryType.GOOD, warehouse.vendor.id, order.warehouse_id, 0)[0]whCursor = warehouseDbConnection.cursor()''' Good Serialized'''if ItemType.SERIALIZED == item.type:for serialNumber in serialNumbers:serialNumber = serialNumber.strip()if len(serialNumber) ==0:raise TransactionServiceException(315, "Serial Number not Specified. Order Id:- "+str(order.id))invItemSql = "select i.id, i.itemId, i.itemNumber, i.serialNumber, i.initialQuantity, i.currentQuantity, i.purchaseId, i.purchaseReturnId, i.currentWarehouseId, i.lastScanType, i.transferStatus, physicalWarehouseId, po.supplierId, l.unitPrice, l.nlc from inventoryItem i join purchase p on i.purchaseId = p.id join purchaseorder po on p.purchaseOrder_id = po.id join lineitem l on (i.itemId = l.itemId and po.id =l.purchaseOrder_id) where i.serialNumber ='%s' order by i.id desc limit 1"%(serialNumber)whCursor.execute(invItemSql)invItem = whCursor.fetchone()if invItem is None:if warehouseDbConnection.open:warehouseDbConnection.close()raise TransactionServiceException(309, "No Item in the inventory with this serial number " + serialNumber+" and Order Id:- "+str(order.id))if item.id!=invItem[1]:if not catalog_client.isAlive():catalog_client = CatalogClient().get_client()sritem = catalog_client.getItem(invItem[1])scanItemString = " ".join([str(sritem.brand), str(sritem.modelName), str(sritem.modelNumber), str(sritem.color)])lineItemString = " ".join([str(lineitem.brand), str(lineitem.model_name), str(lineitem.model_number), str(lineitem.color)])if warehouseDbConnection.open:warehouseDbConnection.close()raise TransactionServiceException(310, "Trying to scan " + scanItemString + " instead of " + lineItemString+" Order Id- "+str(order.id))if order.warehouse_id!= invItem[11]:if warehouseDbConnection.open:warehouseDbConnection.close()raise TransactionServiceException(311, "No Item residing in Billing Warehouse with this serial number " + serialNumber+" and Order Id:- "+str(order.id))if warehouse.id!= invItem[8]:warehouseDbConnection.rollback()if warehouseDbConnection.open:warehouseDbConnection.close()raise TransactionServiceException(311, "No Item residing in Billing Warehouse with this serial number " + serialNumber+" in the vendor warehouse Id"+str(order.fulfilmentWarehouseId)+"and Order Id:- "+str(order.id))if invItem[10] is not None and invItem[10]=='IN_TRANSIT':if warehouseDbConnection.open:warehouseDbConnection.close()raise TransactionServiceException(312, "Trying to Scan In-Transit Inventory " + serialNumber+" and Order Id:- "+str(order.id))if invItem[9]=='MARKED_BAD' or invItem[9]=='DOA_IN' or invItem[9]=='DOA_OUT' or invItem[9]=='DOA_REJECTED' or invItem[9]=='SALE_RET_UNUSABLE' or invItem[9]=='BAD_SALE':if warehouseDbConnection.open:warehouseDbConnection.close()raise TransactionServiceException(313, "Trying to Scan Bad Inventory Serial Number:- " + serialNumber+" and Order Id:- "+str(order.id))scanSql = "select * from scanNew where inventoryItemId =%d order by id"%(invItem[0])whCursor.execute(scanSql)scans = whCursor.fetchall()if scans is None:if warehouseDbConnection.open:warehouseDbConnection.close()raise TransactionServiceException(314, "Item with Serial Number:- " + serialNumber+" never scanned in the system")lastScan = scans[len(scans)-1]if lastScan[3]=='SALE':if warehouseDbConnection.open:warehouseDbConnection.close()raise TransactionServiceException(315, "Inventory Item with serial number- "+ serialNumber+" already scanned against order id- "+str(lastScan[6]))if warehouse.id!=invItem[8]:if warehouseDbConnection.open:warehouseDbConnection.close()raise TransactionServiceException(316, "Inventory Item scanning from vendor warehouse "+str(invItem[8])+" instead of order fulfillment warehouse "+str(warehouse.id)+" order id- "+str(order.id))current_time = datetime.datetime.now()insertScanSql = "insert into scanNew(inventoryItemId, warehouseId, type, scannedAt, quantity, orderId) values(%d,%d,'%s','%s',%d,%d)"%(invItem[0],warehouse.id,'SALE',current_time.strftime('%Y-%m-%d %H:%M:%S'),1,order.id)scanList.append(insertScanSql)#whCursor.execute(insertScanSql)updateInvItemSql = "update inventoryItem set currentQuantity = currentQuantity-1, lastScanType='SALE' where id=%d and serialnumber ='%s'"%(invItem[0],serialNumber)inventoryItemList.append(updateInvItemSql)#whCursor.execute(updateInvItemSql)lineitem.transfer_price = invItem[13]lineitem.nlc = invItem[14]order.vendorId = invItem[12]else:invItemSql = "select i.id, i.itemId, i.itemNumber, i.serialNumber, i.initialQuantity, i.currentQuantity, i.purchaseId, i.purchaseReturnId, i.currentWarehouseId, i.lastScanType, i.transferStatus, physicalWarehouseId, po.supplierId, l.unitPrice, l.nlc from inventoryItem i join purchase p on i.purchaseId = p.id join purchaseorder po on p.purchaseOrder_id = po.id join lineitem l on (i.itemId = l.itemId and po.id =l.purchaseOrder_id) where i.itemId = %d AND i.currentQuantity > 0 AND i.currentWarehouseId = %d AND i.physicalWarehouseId = %d AND i.lastScanType not in ('MARKED_BAD','DOA_IN','DOA_REJECTED','DOA_REPLACED') AND (i.transferStatus is NULL or i.transferStatus != 'IN_TRANSIT')"%(item.id,warehouse.id,order.warehouse_id)whCursor.execute(invItemSql)invItems = whCursor.fetchall()if invItems is None:raise TransactionServiceException(317, "No Item in the inventory with this item number " + itemNumbers[0]+" in Vendor Warehouse Id- "+str(warehouse.id)+" Order Id:- "+str(order.id))if warehouseDbConnection.open:warehouseDbConnection.close()totalCurrentQuantity =0for invItem in invItems:totalCurrentQuantity = totalCurrentQuantity + invItem[5]orderQuantity = lineitem.quantityif totalCurrentQuantity < lineitem.quantity:if warehouseDbConnection.open:warehouseDbConnection.close()raise TransactionServiceException(318, "Unsufficient Quantity with this item number " + itemNumbers[0]+" in Vendor Warehouse Id- "+str(warehouse.id)+" Order Id:- "+str(order.id))usedInventory = 0if nonSerializedUsedInventoryMap.has_key(str(item.id)+"_"+str(warehouse.id)):usedInventory = nonSerializedUsedInventoryMap.get(str(item.id)+"_"+str(warehouse.id))usedInventory = usedInventory+orderQuantitynonSerializedUsedInventoryMap[str(item.id)+"_"+str(warehouse.id)] = usedInventoryelse:usedInventory = orderQuantitynonSerializedUsedInventoryMap[str(item.id)+"_"+str(warehouse.id)] = usedInventoryif usedInventory > totalCurrentQuantity:if warehouseDbConnection.open:warehouseDbConnection.close()raise TransactionServiceException(318, "Unsufficient Quantity with this item number " + itemNumbers[0]+" in Vendor Warehouse Id- "+str(warehouse.id)+" Order Id:- "+str(order.id))for invItem in invItems:scanSql = "select * from scanNew where inventoryItemId =%d order by id"%(invItem[0])whCursor.execute(scanSql)scans = whCursor.fetchall()if scans is None:if warehouseDbConnection.open:warehouseDbConnection.close()raise TransactionServiceException(319, "Item with Item Number:- " + itemNumbers[0]+" never scanned in the system")currentQuantity = invItem[5]scanQuantity = 0if orderQuantity >0:if currentQuantity < orderQuantity:scanQuantity = currentQuantityorderQuantity = orderQuantity - currentQuantityelif currentQuantity > orderQuantity:scanQuantity = orderQuantityorderQuantity = 0else:scanQuantity = currentQuantityorderQuantity = 0else:breakcurrent_time = datetime.datetime.now()insertScanSql = "insert into scanNew(inventoryItemId, warehouseId, type, scannedAt, quantity, orderId) values(%d,%d,'%s','%s',%d,%d)"%(invItem[0],warehouse.id,'SALE',current_time.strftime('%Y-%m-%d %H:%M:%S'),scanQuantity,order.id)print insertScanSqlscanList.append(insertScanSql)#whCursor.execute(insertScanSql)updateInvItemSql = "update inventoryItem set currentQuantity = currentQuantity-%d, lastScanType='SALE' where id=%d "%(scanQuantity,invItem[0])inventoryItemList.append(updateInvItemSql)#whCursor.execute(updateInvItemSql)lineitem.transfer_price = invItem[13]lineitem.nlc = invItem[14]order.vendorId = invItem[12]else:''' Bad Serialized '''if not warehouse.billingWarehouseId:if not inventory_client.isAlive():inventory_client = InventoryClient().get_client()warehouse = inventory_client.getWarehouses(None, InventoryType.GOOD, warehouse.vendor.id, order.warehouse_id, 0)[0]whCursor = warehouseDbConnection.cursor()if ItemType.SERIALIZED == item.type:for serialNumber in serialNumbers:serialNumber = serialNumber.strip()if len(serialNumber) ==0:raise TransactionServiceException(315, "Serial Number not Specified. Order Id:- "+str(order.id))invItemSql = "select i.id, i.itemId, i.itemNumber, i.serialNumber, i.initialQuantity, i.currentQuantity, i.purchaseId, i.purchaseReturnId, i.currentWarehouseId, i.lastScanType, i.transferStatus, physicalWarehouseId, po.supplierId, l.unitPrice, l.nlc from inventoryItem i join purchase p on i.purchaseId = p.id join purchaseorder po on p.purchaseOrder_id = po.id join lineitem l on (i.itemId = l.itemId and po.id =l.purchaseOrder_id) where i.serialNumber ='%s' order by i.id desc limit 1"%(serialNumber)whCursor.execute(invItemSql)invItem = whCursor.fetchone()if invItem is None:if warehouseDbConnection.open:warehouseDbConnection.close()raise TransactionServiceException(110, "No Item in the inventory with this serial number " + serialNumber+" and Order Id:- "+str(order.id))if item.id!=invItem[1]:if not catalog_client.isAlive():catalog_client = CatalogClient().get_client()sritem = catalog_client.getItem(invItem[1])scanItemString = " ".join([str(sritem.brand), str(sritem.modelName), str(sritem.modelNumber), str(sritem.color)])lineItemString = " ".join([str(lineitem.brand), str(lineitem.model_name), str(lineitem.model_number), str(lineitem.color)])if warehouseDbConnection.open:warehouseDbConnection.close()raise TransactionServiceException(110, "Trying to scan " + scanItemString + " instead of " + lineItemString+" Order Id- "+str(order.id))if order.warehouse_id!= invItem[11]:if warehouseDbConnection.open:warehouseDbConnection.close()raise TransactionServiceException(110, "No Item residing in Billing Warehouse with this serial number " + serialNumber+" and Order Id:- "+str(order.id))if order.fulfilmentWarehouseId!= invItem[8]:warehouseDbConnection.rollback()if warehouseDbConnection.open:warehouseDbConnection.close()raise TransactionServiceException(311, "No Item residing in Billing Warehouse with this serial number " + serialNumber+" in the vendor warehouse Id"+str(order.fulfilmentWarehouseId)+"and Order Id:- "+str(order.id))if invItem[10] is not None and invItem[10]=='IN_TRANSIT':if warehouseDbConnection.open:warehouseDbConnection.close()raise TransactionServiceException(110, "Trying to Scan In-Transit Inventory " + serialNumber+" and Order Id:- "+str(order.id))if invItem[9]!='MARKED_BAD' and invItem[9]!='DOA_IN' and invItem[9]!='DOA_REJECTED' and invItem[9]!='SALE_RET_UNUSABLE':if warehouseDbConnection.open:warehouseDbConnection.close()raise TransactionServiceException(110, "Trying to Scan Good Inventory Serial Number:- " + serialNumber+" and Order Id:- "+str(order.id))scanSql = "select * from scanNew where inventoryItemId =%d order by id"%(invItem[0])whCursor.execute(scanSql)scans = whCursor.fetchall()if scans is None:if warehouseDbConnection.open:warehouseDbConnection.close()raise TransactionServiceException(110, "Item with Serial Number:- " + serialNumber+" never scanned in the system")lastScan = scans[len(scans)-1]if lastScan[3]=='BAD_SALE':if warehouseDbConnection.open:warehouseDbConnection.close()raise TransactionServiceException(110, "Inventory Item with serial number- "+ serialNumber+" already scanned against order id- "+str(lastScan[6]))if warehouse.id!=invItem[8]:if warehouseDbConnection.open:warehouseDbConnection.close()raise TransactionServiceException(110, "Inventory Item scanning from vendor warehouse "+str(invItem[8])+" instead of order fulfillment warehouse "+str(warehouse.id)+" order id- "+str(order.id))current_time = datetime.datetime.now()insertScanSql = "insert into scanNew(inventoryItemId, warehouseId, type, scannedAt, quantity, orderId) values(%d,%d,'%s','%s',%d,%d)"%(invItem[0],warehouse.id,'BAD_SALE',current_time.strftime('%Y-%m-%d %H:%M:%S'),1,order.id)scanList.append(insertScanSql)#whCursor.execute(insertScanSql)updateInvItemSql = "update inventoryItem set currentQuantity = currentQuantity-1, lastScanType='BAD_SALE' where id=%d and serialnumber ='%s'"%(invItem[0],serialNumber)inventoryItemList.append(updateInvItemSql)#whCursor.execute(updateInvItemSql)lineitem.transfer_price = invItem[13]lineitem.nlc = invItem[14]order.vendorId = invItem[12]else:invItemSql = "select i.id, i.itemId, i.itemNumber, i.serialNumber, i.initialQuantity, i.currentQuantity, i.purchaseId, i.purchaseReturnId, i.currentWarehouseId, i.lastScanType, i.transferStatus, physicalWarehouseId, po.supplierId, l.unitPrice, l.nlc from inventoryItem i join purchase p on i.purchaseId = p.id join purchaseorder po on p.purchaseOrder_id = po.id join lineitem l on (i.itemId = l.itemId and po.id =l.purchaseOrder_id) where i.itemId = %d AND i.physicalWarehouseId = %d AND lastScanType in ('BAD_SALE', 'MARKED_BAD', 'SALE_RET_UNUSABLE', 'DOA_REJECTED', 'DOA_IN') AND i.currentQuantity >0 AND (i.transferStatus is NULL or i.transferStatus != 'IN_TRANSIT')"%(item.id,order.warehouse_id)whCursor.execute(invItemSql)invItems = whCursor.fetchall()if invItems is None:if warehouseDbConnection.open:warehouseDbConnection.close()raise TransactionServiceException(110, "No Item in the inventory with this item number " + itemNumbers[0]+" in Vendor Warehouse Id- "+str(warehouse.id)+" Order Id:- "+str(order.id))totalCurrentQuantity =0for invItem in invItems:totalCurrentQuantity = totalCurrentQuantity + invItem[5]orderQuantity = lineitem.quantityif totalCurrentQuantity < lineitem.quantity:if warehouseDbConnection.open:warehouseDbConnection.close()raise TransactionServiceException(110, "Unsufficient Quantity with this item number " + itemNumbers[0]+" in Vendor Warehouse Id- "+str(warehouse.id)+" Order Id:- "+str(order.id))usedInventory = 0if nonSerializedUsedInventoryMap.has_key(str(item.id)+"_"+str(warehouse.id)):usedInventory = nonSerializedUsedInventoryMap.get(str(item.id)+"_"+str(warehouse.id))usedInventory = usedInventory+orderQuantitynonSerializedUsedInventoryMap[str(item.id)+"_"+str(warehouse.id)] = usedInventoryelse:usedInventory = orderQuantitynonSerializedUsedInventoryMap[str(item.id)+"_"+str(warehouse.id)] = usedInventoryif usedInventory > totalCurrentQuantity:if warehouseDbConnection.open:warehouseDbConnection.close()raise TransactionServiceException(318, "Unsufficient Quantity with this item number " + itemNumbers[0]+" in Vendor Warehouse Id- "+str(warehouse.id)+" Order Id:- "+str(order.id))for invItem in invItems:scanSql = "select * from scanNew where inventoryItemId =%d order by id"%(invItem[0])whCursor.execute(scanSql)scans = whCursor.fetchall()if scans is None:if warehouseDbConnection.open:warehouseDbConnection.close()raise TransactionServiceException(110, "Item with Item Number:- " + itemNumbers[0]+" never scanned in the system")currentQuantity = invItem[5]scanQuantity = 0if orderQuantity >0:if currentQuantity < orderQuantity:scanQuantity = currentQuantityorderQuantity = orderQuantity - currentQuantityelif currentQuantity > orderQuantity:scanQuantity = orderQuantityorderQuantity = 0else:scanQuantity = currentQuantityorderQuantity = 0else:breakcurrent_time = datetime.datetime.now()insertScanSql = "insert into scanNew(inventoryItemId, warehouseId, type, scannedAt, quantity, orderId) values(%d,%d,'%s','%s',%d,%d)"%(invItem[0],invItem[8],'BAD_SALE',current_time.strftime('%Y-%m-%d %H:%M:%S'),scanQuantity,order.id)scanList.append(insertScanSql)#whCursor.execute(insertScanSql)updateInvItemSql = "update inventoryItem set currentQuantity = currentQuantity-%d, lastScanType='BAD_SALE' where id=%d "%(scanQuantity,invItem[0])inventoryItemList.append(updateInvItemSql)#whCursor.execute(updateInvItemSql)lineitem.transfer_price = invItem[13]lineitem.nlc = invItem[14]order.vendorId = invItem[12]order.fulfilmentWarehouseId = invItem[9]elif billingType == BillingType.OURS_EXTERNAL:try:if ItemType.SERIALIZED == item.type:serialNumber = serialNumbers[0]else:serialNumber = ""if not warehouse_client.isAlive():warehouse_client = WarehouseClient().get_client()inventoryItem = warehouse_client.scanForOursExternalSale(lineitem.item_id, serialNumber, lineitem.item_number, invoice_number, order.fulfilmentWarehouseId, lineitem.transfer_price, lineitem.nlc, order.id)lineitem.transfer_price = inventoryItem.unitPricelineitem.nlc = inventoryItem.nlcorder.vendorId = inventoryItem.supplierIdexcept WarehouseServiceException as e:print sys.exc_info()[0]print 'Could not scan out orders due to: ' + e.messageraise TransactionServiceException(110, e.message)else:if not warehouse.isAvailabilityMonitored:if not inventory_client.isAlive():inventory_client = InventoryClient().get_client()inventory_client.addInventory(item.id, warehouse.id, -1 * lineitem.quantity)orderscansMap[order.id] = scanListorderInventoryItemMap[order.id] = inventoryItemListorderFulfilmentWarehouseMap[order.id] = warehousefor order in ordersList:if billingType == BillingType.OURS:scanList = orderscansMap.get(order.id)#print order.id#print scanListinventoryItemList = orderInventoryItemMap.get(order.id)fulfillmentWarehouse = orderFulfilmentWarehouseMap.get(order.id)lineItem = order.lineitems[0]whCursor = warehouseDbConnection.cursor()for scan in scanList:whCursor.execute(scan)for invItem in inventoryItemList:whCursor.execute(invItem)if order.productCondition != ProductCondition.BAD:if fulfillmentWarehouse.billingType == BillingType.OURS:if not inventory_client.isAlive():inventory_client = InventoryClient().get_client()inventory_client.addInventory(lineItem.item_id, fulfillmentWarehouse.id, long(-1.0*lineItem.quantity))if order.freebieItemId:inventoryItem = Nonefor freebieWhId in freebieWarehouseIdMap.get(order.id):try:warehouse_client = WarehouseClient().get_client()inventoryItem = warehouse_client.scanfreebie(orderId, order.freebieItemId, freebieWhId, ScanType.SALE);except Exception as e:print e.messageraise TransactionServiceException(110,'Error in billing freebie for warehouseId ' + str(freebieWarehouseId))attr = Attribute()attr.orderId = orderIdattr.name = "freebie_tp"attr.value = str(inventoryItem.unitPrice)attr1 = Attribute()attr1.orderId = orderIdattr1.name = "freebie_vendor"attr1.value = str(inventoryItem.supplierId)attr2 = Attribute()attr2.orderId = orderIdattr2.name = "freebie_nlc"attr2.value = str(inventoryItem.nlc)if order.productCondition != ProductCondition.BAD:'''Reduce the reservation count for all line items of the given order.'''try:if not inventory_client.isAlive():inventory_client = InventoryClient().get_client()for lineitem in order.lineitems:inventory_client.reduceReservationCount(lineitem.item_id, order.fulfilmentWarehouseId, sourceId, order.id, lineitem.quantity)except:print "Unable to reduce reservation count"warehouseDbConnection.commit()if warehouseDbConnection.open:warehouseDbConnection.close()session.commit()if billingType == BillingType.OURS or billingType == BillingType.OURS_EXTERNAL:#get seller for current warehouse idseller_id = __get_seller(order.warehouse_id)whaddressmapping = WarehouseAddressMapping.query.filter_by(warehouse_id=ordersList[0].warehouse_id).one()invoiceNumber = get_next_invoice_counter(seller_id, ordersList[0].warehouse_id, hsnCode)invoiceTypeVal = 1if not individualInvoice:invoiceTypeVal = 2if lineItemSize > 1:invoiceTypeVal = 2if lineItemSize <= 1 and invoiceType =="BulkInvoice" :invoiceTypeVal = 2if ordersList[0].logisticsTransactionId:transactionShipSeqValues = ordersList[0].logisticsTransactionId.split('-')txnShipSeq = TransactionShipmentSequence.query.filter(TransactionShipmentSequence.transactionId==int(transactionShipSeqValues[0])).filter(TransactionShipmentSequence.sequence==int(transactionShipSeqValues[1])).order_by(desc(TransactionShipmentSequence.id)).first()txnShipSeq.invoiceFormat = invoiceTypeValfor order in ordersList:order.invoice_number = invoiceNumberorder.seller_id = seller_idorder.warehouse_address_id = whaddressmapping.address_id# logisticCostDetail= ShipmentLogisticsCostDetail.get_by(logisticsTransactionId=ordersList[0].logisticsTransactionId)# logisticCostDetail.packageDimensions = packageDimensionssession.commit()return Truedef get_invoice_format_logistics_txn_id(transactionId, shipementSeq):txnShipSeq = TransactionShipmentSequence.query.filter(TransactionShipmentSequence.transactionId==transactionId).filter(TransactionShipmentSequence.sequence==shipementSeq).order_by(desc(TransactionShipmentSequence.id)).first()if txnShipSeq.invoiceFormat == 2:return 'Bulk'else:return 'Individual'def create_homeshop_order(hsOrder):hs_Order = HsOrder()hs_Order.orderId = hsOrder.orderIdhs_Order.catalogueName = hsOrder.catalogueNamehs_Order.courierName = hsOrder.courierNamehs_Order.hsItemId = hsOrder.hsItemIdhs_Order.hsOrderDate = to_py_date(hsOrder.hsOrderDate)hs_Order.hsOrderNo = hsOrder.hsOrderNohs_Order.hsProductId = hsOrder.hsProductIdhs_Order.hsSubOrderNo = hsOrder.hsSubOrderNohs_Order.paymentMode = hsOrder.paymentModehs_Order.sellerSku = hsOrder.sellerSkuhs_Order.slaDays = hsOrder.slaDayshs_Order.shippingName = hsOrder.shippingNameorder = Order.get_by(id=hsOrder.orderId)order.status = OrderStatus.ACCEPTEDorder.accepted_timestamp = datetime.datetime.now()user = Nonetry:user_client = UserClient().get_client()user_to_add = User()user_to_add.email = 'HS.'+ str(hsOrder.orderId) + '@mailinator.com'user_to_add.password = 'ouBPONyDYWfeAFtXeaYRkQ'user_to_add.communicationEmail = user_to_add.emailuser_to_add.sourceStartTime = int(round(time.time() * 1000))user_to_add.sourceId = OrderSource.HOMESHOP18user_to_add.sex = Sex.WONT_SAYuser_to_add = user_client.createUser(user_to_add)user = user_to_addexcept:passif user:order.customer_id = user.userIdorder.customer_email = user.emailsession.commit()def get_homeshop_order(order_id, hsOrderNo, hsSubOrderNo):query = HsOrder.queryif order_id:query = query.filter(HsOrder.orderId == order_id)if hsOrderNo:query = query.filter(HsOrder.hsOrderNo == hsOrderNo)if hsSubOrderNo:query = query.filter(HsOrder.hsSubOrderNo == hsSubOrderNo)return query.all()def homeshop_order_exists(hs_OrderNo, hs_SubOrderNo):exists = HsOrder.query.filter_by(hsOrderNo=hs_OrderNo,hsSubOrderNo=hs_SubOrderNo).first()if exists is not None:return Trueelse:return Falsedef split_bulk_order(order_id, split_order_quantity):order = get_order(order_id)if split_order_quantity >=order.lineitems[0].quantity:raise TransactionServiceException(115, "Split Quantity is greater than or equal to order quantity")if order.status not in [OrderStatus.SUBMITTED_FOR_PROCESSING,OrderStatus.INVENTORY_LOW,OrderStatus.LOW_INV_PO_RAISED,OrderStatus.LOW_INV_REVERSAL_IN_PROCESS,OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT,OrderStatus.CAPTURE_IN_PROCESS, OrderStatus.REJECTED]:raise TransactionServiceException(115, "Order not allowed to be split")new_order = __copy_order(order)new_order.originalOrderId=order.idnew_order.lineitems[0].quantity = split_order_quantitynew_order.logistics_provider_id = order.logistics_provider_idnew_order.lineitems[0].logisticsCost = round((order.lineitems[0].logisticsCost/order.lineitems[0].quantity)*split_order_quantity,2)order.lineitems[0].logisticsCost = order.lineitems[0].logisticsCost - new_order.lineitems[0].logisticsCostif order.cod:new_order.lineitems[0].codCollectionCharges = round((order.lineitems[0].codCollectionCharges/order.lineitems[0].quantity)*split_order_quantity,2)order.lineitems[0].codCollectionCharges = order.lineitems[0].codCollectionCharges - new_order.lineitems[0].codCollectionChargesnew_order.lineitems[0].total_price = new_order.lineitems[0].unit_price*split_order_quantitynew_order.lineitems[0].total_weight = new_order.lineitems[0].unit_weight*split_order_quantitynew_order.total_amount = new_order.lineitems[0].total_pricenew_order.total_weight = new_order.lineitems[0].total_weightnew_order.shippingCost = round((order.shippingCost/order.lineitems[0].quantity)*split_order_quantity,0)new_order.shippingRefund = round((order.shippingRefund/order.lineitems[0].quantity)*split_order_quantity,0)order.lineitems[0].quantity = order.lineitems[0].quantity - split_order_quantityorder.lineitems[0].total_price = order.lineitems[0].unit_price * order.lineitems[0].quantityorder.lineitems[0].total_weight = order.lineitems[0].unit_weight*order.lineitems[0].quantityorder.total_amount = order.lineitems[0].total_priceorder.total_weight = order.lineitems[0].total_weightorder.shippingCost = order.shippingCost - new_order.shippingCostnew_order.net_payable_amount = new_order.total_amount + new_order.shippingCostorder.net_payable_amount = order.total_amount + order.shippingCostnew_order.wallet_amount = 0if order.wallet_amount > 0:wallet_amount = order.wallet_amountfirst_order = new_ordersecond_order = orderif new_order.net_payable_amount > order.net_payable_amount:first_order = ordersecond_order = new_orderfirst_order.wallet_amount = min(first_order.total_amount + first_order.shippingCost, wallet_amount)first_order.net_payable_amount = first_order.total_amount + first_order.shippingCost - first_order.wallet_amountsecond_order.wallet_amount = wallet_amount - first_order.wallet_amountsecond_order.net_payable_amount = second_order.total_amount + second_order.shippingCost - second_order.wallet_amount#Add attributes during splitattributes = Attribute.query.filter(Attribute.orderId == order.id).all()if attributes:for attribute in attributes:newattribute = Attribute()newattribute.orderId = new_order.idnewattribute.name = attribute.namenewattribute.value = attribute.valuesession.commit()inventoryClient = InventoryClient().get_client()inventoryClient.reserveItemInWarehouse(new_order.lineitems[0].item_id, new_order.fulfilmentWarehouseId, sourceId, new_order.id, to_java_date(new_order.created_timestamp), to_java_date(new_order.promised_shipping_time), new_order.lineitems[0].quantity)inventoryClient.reduceReservationCount(order.lineitems[0].item_id, order.fulfilmentWarehouseId, sourceId, order.id, new_order.lineitems[0].quantity)html = """<html><body><div><p>Dear Customer,</p><p>Your order: """+str(order.id)+""" have been split into following orders:-<br><br><div><table><tr><td colspan="8"><hr /></td></tr><tr><td colspan="8" align="left"><b>Order Details</b></td></tr><tr><td colspan="8"><hr /></td></tr><tr><th width="100">Order Id</th><th>Product Name</th><th width="100">Quantity</th><th width="100">Unit Price</th><th width="100">Amount</th></tr>"""html += """<tr><td align="center">"""+str(order.id)+"""</td><td>"""+str(order.lineitems[0])+"""</td><td align="center">"""+("%.0f" % order.lineitems[0].quantity)+"""</td><td align="center">"""+("%.2f" % order.lineitems[0].unit_price)+"""</td><td align="center">"""+("%.2f" % round(order.lineitems[0].total_price,2))+"""</td></tr>"""html += """<tr><td align="center">"""+str(new_order.id)+"""</td><td>"""+str(new_order.lineitems[0])+"""</td><td align="center">"""+("%.0f" % new_order.lineitems[0].quantity)+"""</td><td align="center">"""+("%.2f" % new_order.lineitems[0].unit_price)+"""</td><td align="center">"""+("%.2f" % round(new_order.lineitems[0].total_price,2))+"""</td></tr>"""html += """</table><p>For any queries please call +918826894203.</p><p>Warm Regards,<br />SmartDukaan Team</p></div></body></html>"""subject = "Your Smart Dukaan Order: "+str(order.id) + " have been split"bcc = ["backup@saholic.com"]try:helper_client = HelperClient(host_key = "helper_service_server_host_prod").get_client()helper_client.saveUserEmailForSending([order.customer_email], SaholicHelpEmailId, subject, html, str(order.id), "TransactionInfo", [], bcc, order.source)#if order.customer_mobilenumber is not None:# smsText = "Dear Customer, Your Order "+ str(order.id) + " have been split into two orders. Please check your account or email. For any queries please call +918826894203."# send_transaction_sms(order.customer_id, order.customer_mobilenumber, smsText, SmsType.TRANSACTIONAL, False)except Exception as e:print ereturn new_orderdef __verify_order(order):logging.info("Verifying order no: " + str(order.id))if order.status == OrderStatus.COD_VERIFICATION_PENDING:order.status = OrderStatus.SUBMITTED_FOR_PROCESSINGorder.statusDescription = "Submitted for processing"order.verification_timestamp = datetime.datetime.now()session.commit()if order.source == OrderSource.STORE:sod = StoreOrderDetail.get_by(orderId = order.id)__push_store_collection_to_hotspot(order, "advance", sod.cashAmount, sod.cardAmount)logging.info("Successfully verified order no: " + str(order.id))return Trueelse:logging.warning("Verify called for order no." + str(order.id) +" which is not in verification pending state");return Falsedef verify_orders_for_transaction(transactionId):transaction = get_transaction(transactionId)for order in transaction.orders:__verify_order(order)return Truedef get_creditor_info(creditorId):return Creditor.get_by(id=creditorId)def update_creditor_info(creditor):t_creditor = get_creditor_info(creditor.id)t_creditor.active = creditor.activeif t_creditor.name != creditor.name:t_creditor.name = creditor.namesession.commit()return Truedef get_user_sanction_details(userId, creditorId):us_query = UserSanction.queryif userId:us_query = us_query.filter(UserSanction.user_id == userId)if creditorId:us_query = us_query.filter(UserSanction.creditor_id == creditorId)us_query = us_query.filter(UserSanction.active == True)allSanctions = us_query.all()returnMap = {}for sanction in allSanctions:ticket_size = -1if creditorTicketSizeMap.has_key(sanction.creditor_id):ticket_size = creditorTicketSizeMap.get(sanction.creditor_id)else:fetchCreditorTicketSizeMap()ticket_size = creditorTicketSizeMap.get(sanction.creditor_id)if returnMap.has_key(sanction.creditor_id):creditorMap = returnMap.get(sanction.creditor_id)creditorMap['TicketSize'] = ticket_sizeif creditorMap.has_key('Sanctions'):sanctionsList = creditorMap.get('Sanctions')sanctionsList.append(sanction)creditorMap['Sanctions'] = sanctionsListelse:sanctionsList =[]sanctionsList.append(sanction)creditorMap['Sanctions'] = sanctionsListreturnMap[sanction.creditor_id] = creditorMapelse:creditorMap = {}creditorMap['TicketSize'] = ticket_sizesanctionsList =[]sanctionsList.append(sanction)creditorMap['Sanctions'] = sanctionsListreturnMap[sanction.creditor_id] = creditorMapreturn returnMapdef get_user_sanction_details_paginated(userId, creditorId, limit=0, offset=0,sort="Default"):totalCount = UserSanction.query.filter(UserSanction.active == True).count()hasMore = Falseif limit >0 and (limit+offset) < totalCount:hasMore = Trueus_query = UserSanction.queryif userId:us_query = us_query.filter(UserSanction.user_id == userId)if creditorId:us_query = us_query.filter(UserSanction.creditor_id == creditorId)us_query = us_query.filter(UserSanction.active == True)if sort == 'loan':us_query = us_query.order_by(desc(UserSanction.loan))if limit>0:us_query = us_query.limit(limit)if offset>0 and limit >0:us_query = us_query.offset(offset)allSanctions = us_query.all()returnMap = {}for sanction in allSanctions:ticket_size = -1if creditorTicketSizeMap.has_key(sanction.creditor_id):ticket_size = creditorTicketSizeMap.get(sanction.creditor_id)else:fetchCreditorTicketSizeMap()ticket_size = creditorTicketSizeMap.get(sanction.creditor_id)if returnMap.has_key(sanction.creditor_id):creditorMap = returnMap.get(sanction.creditor_id)creditorMap['TicketSize'] = ticket_sizeif creditorMap.has_key('Sanctions'):sanctionsList = creditorMap.get('Sanctions')sanctionsList.append(sanction)creditorMap['Sanctions'] = sanctionsListelse:sanctionsList =[]sanctionsList.append(sanction)creditorMap['Sanctions'] = sanctionsListreturnMap[sanction.creditor_id] = creditorMapelse:creditorMap = {}creditorMap['TicketSize'] = ticket_sizesanctionsList =[]sanctionsList.append(sanction)creditorMap['Sanctions'] = sanctionsListreturnMap[sanction.creditor_id] = creditorMapreturn hasMore, totalCount, returnMapdef update_user_sanction(userSanction):userS = UserSanction.get_by(id=userSanction.id)if userS is None:return Falseelse:userS.credit_blocked = userSanction.credit_blockeduserS.loan = userSanction.loanuserS.active = userSanction.activesession.commit()return Truedef __get_user_sanction(sanctionId):return UserSanction.get_by(id=sanctionId)def get_credit_history_records(paymentId, userId, creditorId, creditTxnType, limit=0, offset=0):credit_hs_query = CreditHistory.queryif paymentId and paymentId>0:credit_hs_query = credit_hs_query.filter(CreditHistory.payment_id==paymentId)if userId and userId>0:credit_hs_query = credit_hs_query.filter(CreditHistory.user_id==userId)if creditorId and creditorId>0:credit_hs_query = credit_hs_query.filter(CreditHistory.creditor_id==creditorId)if creditTxnType:credit_hs_query = credit_hs_query.filter(CreditHistory.credit_type==CreditTxnType._VALUES_TO_NAMES[creditTxnType])credit_hs_query = credit_hs_query.order_by(desc(CreditHistory.created))if limit>0:credit_hs_query = credit_hs_query.limit(limit)if offset>0 and limit >0:credit_hs_query = credit_hs_query.offset(offset)return credit_hs_query.all()def get_credit_history_records_paginated(paymentId, userId, creditorId, creditTxnType, limit=0, offset=0):totalCount = CreditHistory.query.count()hasMore = Falseif limit >0 and (limit+offset) < totalCount:hasMore = Truecredit_hs_query = CreditHistory.queryif paymentId and paymentId>0:credit_hs_query = credit_hs_query.filter(CreditHistory.payment_id==paymentId)if userId and userId>0:credit_hs_query = credit_hs_query.filter(CreditHistory.user_id==userId)if creditorId and creditorId>0:credit_hs_query = credit_hs_query.filter(CreditHistory.creditor_id==creditorId)if creditTxnType:credit_hs_query = credit_hs_query.filter(CreditHistory.credit_type==CreditTxnType._VALUES_TO_NAMES[creditTxnType])credit_hs_query = credit_hs_query.order_by(desc(CreditHistory.created))if limit>0:credit_hs_query = credit_hs_query.limit(limit)if offset>0 and limit >0:credit_hs_query = credit_hs_query.offset(offset)return hasMore, totalCount, credit_hs_query.all()def process_credit_transaction(paymentId, userId, creditorId, creditTxns, invoiceNumber=None):us_query = UserSanction.queryif userId:us_query = us_query.filter(UserSanction.user_id == userId)if creditorId:us_query = us_query.filter(UserSanction.creditor_id == creditorId)userSanctions = us_query.all()if userSanctions is None or len(userSanctions)==0:logging.info("No Credit Sanction Details Availble. UserId:- "+str(userId)+ " Creditor Id:- "+ str(creditorId))raise TransactionServiceException(221, "No Credit Sanction Details Availble. UserId:- "+str(userId)+ " Creditor Id:- "+ str(creditorId))userSanction = userSanctions[0]availableCredit = userSanction.credit_limit - (userSanction.credit_blocked + userSanction.loan)amountToReversed = 0amountToLoan = 0amountToBlocked = 0creditHistoryTotal = 0allCreditTxns = get_credit_history_records(paymentId, userId, creditorId, None)for credit_txn in allCreditTxns:creditHistoryTotal = creditHistoryTotal + credit_txn.amountif creditHistoryTotal < 0:logging.info("Error: Credit History is Negative. Payment Id:- "+str(paymentId))raise TransactionServiceException(222, "Error: Credit History is Negative. Payment Id:- "+str(paymentId))for creditTxn in creditTxns:if creditTxn.credit_type in [CreditTxnType.BLOCKED_REVERSED]:amountToReversed = amountToReversed + creditTxn.amountif creditTxn.credit_type in [CreditTxnType.LOAN]:amountToLoan = amountToLoan + creditTxn.amountif creditTxn.credit_type in [CreditTxnType.BLOCKED]:amountToBlocked = amountToBlocked + creditTxn.amountif amountToLoan > userSanction.credit_blocked:logStr = "Error: Not Enough Credit to Process For Loan. Payment Id:- "+str(paymentId) + " Shipping Id:- "+str(creditTxns[0].shipping_id)+" Amount to Loan:- "+str(amountToLoan)+ " Credit Blocked:- "+str(userSanction.credit_blocked)logging.info(logStr)raise TransactionServiceException(224, "Error: Not Enough Credit to Process For Loan. Payment Id:- "+str(paymentId) + " Shipping Id:- "+str(creditTxns[0].shipping_id)+ " Amount to Loan:- "+str(amountToLoan)+ " Credit Blocked:- "+str(userSanction.credit_blocked))if amountToReversed > userSanction.credit_blocked:logStr= "Error: Not Enough Credit to Process For Reversal. Payment Id:- "+str(paymentId) + " Shipping Id:- "+str(creditTxns[0].shipping_id)+ " Amount to Reverse:- "+str(amountToReversed)+ " Credit Blocked:- "+str(userSanction.credit_blocked)logging.info(logStr)raise TransactionServiceException(225, "Error: Not Enough Credit to Process For Reversal. Payment Id:- "+str(paymentId) + " Shipping Id:- "+str(creditTxns[0].shipping_id)+ " Amount to Reverse:- "+str(amountToReversed)+ " Credit Blocked:- "+str(userSanction.credit_blocked))if amountToBlocked > availableCredit:logStr = "Error: Not Enough Credit to be Blocked. Payment Id:- "+str(paymentId) + " Shipping Id:- "+str(creditTxns[0].shipping_id)+" Amount to Block:- "+str(amountToBlocked)+ " Credit Blocked:- "+str(userSanction.credit_blocked)logging.info(logStr)raise TransactionServiceException(226, "Error: Not Enough Credit to be Blocked. Payment Id:- "+str(paymentId) + " Shipping Id:- "+str(creditTxns[0].shipping_id)+" Amount to Block:- "+str(amountToBlocked)+ " Credit Blocked:- "+str(userSanction.credit_blocked))for creditTxn in creditTxns:creditHistoryRec = CreditHistory.get_by(payment_id=paymentId,shipping_id=creditTxn.shipping_id)if creditHistoryRec is None:creditHistoryRec = CreditHistory()creditHistoryRec.user_id = userIdcreditHistoryRec.creditor_id = creditorIdcreditHistoryRec.payment_id = paymentIdcreditHistoryRec.amount = creditTxn.amount * creditTxnMultiplierMap.get(creditTxn.credit_type)creditHistoryRec.credit_type = CreditTxnType._VALUES_TO_NAMES[creditTxn.credit_type]creditHistoryRec.shipping_id = creditTxn.shipping_iduserSanction.credit_blocked = userSanction.credit_blocked + (creditTxn.amount * creditTxnMultiplierMap.get(creditTxn.credit_type))if creditTxn.credit_type in [CreditTxnType.LOAN]:userSanction.loan = userSanction.loan + creditTxn.amountloanHistoryRec = LoanHistory()loanHistoryRec.user_id = userIdloanHistoryRec.creditor_id = creditorIdloanHistoryRec.payment_id = paymentIdloanHistoryRec.amount = creditTxn.amount * loanTxnMultplierMap.get(creditTxn.credit_type)loanHistoryRec.credit_type = CreditTxnType._VALUES_TO_NAMES[creditTxn.credit_type]loanHistoryRec.loan_id = creditTxn.shipping_idif invoiceNumber is not None:loanHistoryRec.invoiceNumber = invoiceNumberif creditorDueDateMap.has_key(creditorId):due_days = creditorDueDateMap.get(creditorId)loanHistoryRec.due_date = datetime.datetime.now()+timedelta(days=due_days)else:fetchCreditorDueDateMap()due_days = creditorDueDateMap.get(creditorId)loanHistoryRec.due_date = datetime.datetime.now()+timedelta(days=due_days)else:logging.info("Error: Entry already existed for "+str(paymentId) + " Shipping Id:- "+str(creditTxns[0].shipping_id) +" Credit Txn Type:- "+CreditTxnType._VALUES_TO_NAMES[creditTxn.credit_type]+ " in Credit History ")raise TransactionServiceException(227, "Error: Entry already existed for "+str(paymentId) + " Shipping Id:- "+str(creditTxns[0].shipping_id) +" Credit Txn Type:- "+CreditTxnType._VALUES_TO_NAMES[creditTxn.credit_type]+ " in Credit History ")return Truedef get_loan_payable_for_user_to_creditor(userId, creditorId, dueDate):loanhistoryRecords = LoanHistory.query.filter(and_(LoanHistory.user_id==userId, LoanHistory.creditor_id==creditorId, LoanHistory.due_date<to_py_date(dueDate), LoanHistory.updated is None)).all()loanAmount = 0for loanHistory in loanhistoryRecords:loanAmount = loanAmount + loanHistory.amountreturn loanAmountdef get_loan_history_records(paymentId, userId, creditorId, creditTxnType, limit=0, offset=0):loan_hs_query = LoanHistory.queryif paymentId and paymentId>0:loan_hs_query = loan_hs_query.filter(LoanHistory.payment_id==paymentId)if userId and userId>0:loan_hs_query = loan_hs_query.filter(LoanHistory.user_id==userId)if creditorId and creditorId>0:loan_hs_query = loan_hs_query.filter(LoanHistory.creditor_id==creditorId)if creditTxnType:loan_hs_query = loan_hs_query.filter(LoanHistory.credit_type==CreditTxnType._VALUES_TO_NAMES[creditTxnType])loan_hs_query = loan_hs_query.order_by(desc(LoanHistory.created))if limit>0:loan_hs_query = loan_hs_query.limit(limit)if offset>0 and limit>0:loan_hs_query = loan_hs_query.offset(offset)return loan_hs_query.all()def get_loan_history_records_paginated(paymentId, userId, creditorId, creditTxnType, limit=0, offset=0):totalCount = LoanHistory.query.count()hasMore = Falseif limit >0 and (limit+offset) < totalCount:hasMore = Trueloan_hs_query = LoanHistory.queryif paymentId and paymentId>0:loan_hs_query = loan_hs_query.filter(LoanHistory.payment_id==paymentId)if userId and userId>0:loan_hs_query = loan_hs_query.filter(LoanHistory.user_id==userId)if creditorId and creditorId>0:loan_hs_query = loan_hs_query.filter(LoanHistory.creditor_id==creditorId)if creditTxnType:loan_hs_query = loan_hs_query.filter(LoanHistory.credit_type==CreditTxnType._VALUES_TO_NAMES[creditTxnType])loan_hs_query = loan_hs_query.order_by(desc(LoanHistory.created))if limit>0:loan_hs_query = loan_hs_query.limit(limit)if offset>0 and limit>0:loan_hs_query = loan_hs_query.offset(offset)return hasMore, totalCount, loan_hs_query.all()def process_loan_transaction(paymentId, userId, creditorId, loantxns):us_query = UserSanction.queryif userId:us_query = us_query.filter(UserSanction.user_id == userId)if creditorId:us_query = us_query.filter(UserSanction.creditor_id == creditorId)userSanctions = us_query.all()if userSanctions is None or len(userSanctions)==0:logging.info("No Credit Sanction Details Availble. UserId:- "+str(userId)+ " Creditor Id:- "+ str(creditorId))raise TransactionServiceException(227, "No Credit Sanction Details Availble. UserId:- "+str(userId)+ " Creditor Id:- "+ str(creditorId))userSanction = userSanctions[0]amountToLoan = 0amountToLoanPaid = 0amountToCorrected = 0loanHistoryTotal = 0allLoanTxns = get_loan_history_records(paymentId, userId, creditorId, None)for loan_txn in allLoanTxns:loanHistoryTotal = loanHistoryTotal + loan_txn.amountif loanHistoryTotal < 0:logging.info("Error: Loan History is Negative. Payment Id:- "+str(paymentId))raise TransactionServiceException(228, "Error: Loan History is Negative. Payment Id:- "+str(paymentId))for loanTxn in loantxns:if loanTxn.credit_type in [CreditTxnType.LOAN]:amountToLoan = amountToLoan + loanTxn.amountif loanTxn.credit_type in [CreditTxnType.PAID]:amountToLoanPaid = amountToLoanPaid + loanTxn.amountif loanTxn.credit_type in [CreditTxnType.CORRECTION]:amountToCorrected = amountToCorrected + loanTxn.amountif amountToLoan > userSanction.loan:logging.info("Error: Loan required is more than specified. Payment Id:- "+str(paymentId) + " Shipping Id:- "+str(loantxns[0].loan_id))raise TransactionServiceException(229, "Error: Loan required is more than specified. Payment Id:- "+str(paymentId) + " Shipping Id:- "+str(loantxns[0].loan_id))if amountToLoanPaid > userSanction.loan:logging.info("Error: Can't Pay more than Loan Amount. Payment Id:- "+str(paymentId) + " Shipping Id:- "+str(loantxns[0].loan_id))raise TransactionServiceException(230, "Error: Can't Pay more than Loan Amount. Payment Id:- "+str(paymentId) + " Shipping Id:- "+str(loantxns[0].loan_id))if amountToCorrected > userSanction.loan:logging.info("Error: Correction Amount More than loan Amount. Payment Id:- "+str(paymentId) + " Shipping Id:- "+str(loantxns[0].loan_id))raise TransactionServiceException(231, "Error: Correction Amount More than loan Amount. Payment Id:- "+str(paymentId) + " Shipping Id:- "+str(loantxns[0].loan_id))for loanTxn in loantxns:if loanTxn.credit_type in [CreditTxnType.PAID]:loanHistoryRecords = LoanHistory.query.filter(LoanHistory.loan_id==loanTxn.loan_id).filter(LoanHistory.payment_id==paymentId).all()loanTotalHistory = 0for loanHistoryRec in loanHistoryRecords:loanTotalHistory = loanTotalHistory + loanHistoryRec.amountif loanTotalHistory <= 0:logging.info("Error: Loan Already Paid or Closed for "+str(paymentId) + " Loan Id:- "+str(loanTxn.loan_id) +" Loan Txn Type:- "+CreditTxnType._VALUES_TO_NAMES[loanTxn.credit_type])raise TransactionServiceException(227, "Error: Loan Already Paid or Closed for "+str(paymentId) + " Loan Id:- "+str(loanTxn.loan_id) +" Loan Txn Type:- "+CreditTxnType._VALUES_TO_NAMES[loanTxn.credit_type])else:loanHistoryRec = LoanHistory()loanHistoryRec.user_id = userIdloanHistoryRec.creditor_id = creditorIdloanHistoryRec.payment_id = paymentIdloanHistoryRec.amount = loanTxn.amount * loanTxnMultplierMap.get(loanTxn.credit_type)loanHistoryRec.credit_type = CreditTxnType._VALUES_TO_NAMES[loanTxn.credit_type]loanHistoryRec.loan_id = loanTxn.loan_idloanHistoryRec.invoiceNumber = loanTxn.invoiceNumberif loanTxn.value_date:loanHistoryRec.value_date = to_py_date(loanTxn.value_date)userSanction.loan = userSanction.loan + (loanTxn.amount * loanTxnMultplierMap.get(loanTxn.credit_type))else:loanHistoryRec = LoanHistory.get_by(payment_id=paymentId,loan_id=loanTxn.loan_id, credit_type=CreditTxnType._VALUES_TO_NAMES[loanTxn.credit_type])if loanHistoryRec is None:loanHistoryRec = LoanHistory()loanHistoryRec.user_id = userIdloanHistoryRec.creditor_id = creditorIdloanHistoryRec.payment_id = paymentIdloanHistoryRec.amount = loanTxn.amount * loanTxnMultplierMap.get(loanTxn.credit_type)loanHistoryRec.credit_type = CreditTxnType._VALUES_TO_NAMES[loanTxn.credit_type]loanHistoryRec.loan_id = loanTxn.loan_idloanHistoryRec.invoiceNumber = loanTxn.invoiceNumberif loanTxn.value_date:loanHistoryRec.value_date = to_py_date(loanTxn.value_date)if loanTxn.credit_type in [CreditTxnType.LOAN]:if creditorDueDateMap.has_key(creditorId):due_days = creditorDueDateMap.get(creditorId)loanHistoryRec.due_date = datetime.datetime.now()+timedelta(days=due_days)else:fetchCreditorDueDateMap()due_days = creditorDueDateMap.get(creditorId)loanHistoryRec.due_date = datetime.datetime.now()+timedelta(days=due_days)if loanTxn.credit_type in [CreditTxnType.CORRECTION]:userSanction.loan = userSanction.loan + (loanTxn.amount * loanTxnMultplierMap.get(loanTxn.credit_type))else:logging.info("Error: Entry already existed for "+str(paymentId) + " Loan Id:- "+str(loanTxn.loan_id) +" Loan Txn Type:- "+CreditTxnType._VALUES_TO_NAMES[loanTxn.credit_type])raise TransactionServiceException(227, "Error: Entry already existed for "+str(paymentId) + " Loan Id:- "+str(loanTxn.loan_id) +" Loan Txn Type:- "+CreditTxnType._VALUES_TO_NAMES[loanTxn.credit_type])session.commit()return True#paymentId is transaction iddef __loanHistoryObj(user_id, creditor_id, paymentId, amount, credit_type, loan_id, value_date=None, invoiceNumber=None):loanobj = TLoanHistory()loanobj.user_id = user_idloanobj.creditor_id = creditor_idloanobj.payment_id = paymentIdloanobj.amount = amountloanobj.credit_type = credit_typeloanobj.loan_id = loan_idif value_date is not None:loanobj.value_date = to_java_date(value_date)if invoiceNumber is not None:loanobj.invoiceNumber = invoiceNumberreturn loanobjdef __creditHistoryObj(user_id, creditor_id, paymentId, amount, credit_type, shipping_id):creditObj = TCreditHistory()creditObj.user_id = user_idcreditObj.creditor_id = creditor_idcreditObj.payment_id = paymentIdcreditObj.amount = amountcreditObj.credit_type = credit_typecreditObj.shipping_id = shipping_idreturn creditObjdef get_outstanding_payments(fetchType,userId=0,limit=100):if fetchType =='loan':return fetch_outstanding_loans(userId,limit)elif fetchType =='credit':return fetch_outstanding_credits(userId,limit)else:return Nonedef fetch_outstanding_loans(userId,limit):userCounterMap={}try:loan_os_query = session.query(LoanHistory.user_id,LoanHistory.creditor_id,LoanHistory.payment_id,func.sum(LoanHistory.amount).label('totalAmount'),func.max(LoanHistory.due_date).label('createdDate'))user_client = UserClient().get_client()if userId>0:loan_os_query = loan_os_query.filter(LoanHistory.user_id==userId)loan_os_result = loan_os_query.group_by(LoanHistory.payment_id).having(func.sum(LoanHistory.amount)>0).order_by(func.max(LoanHistory.id)).all()if loan_os_result is not None or len(loan_os_result)>0:userIds=[]for r in loan_os_result:userIds.append(r.user_id)userCounterMap = user_client.getCounterName(userIds)return userCounterMap, loan_os_resultexcept Exception as e:print edef fetch_outstanding_credits(userId,limit):userCounterMap={}try:credit_os_query = session.query(CreditHistory.user_id,CreditHistory.creditor_id,CreditHistory.payment_id,func.sum(CreditHistory.amount).label('totalAmount'),(CreditHistory.created).label('createdDate'))user_client = UserClient().get_client()if userId>0:credit_os_query = credit_os_query.filter(CreditHistory.user_id==userId)credit_os_result = credit_os_query.group_by(CreditHistory.payment_id).having(func.sum(CreditHistory.amount)>0).order_by(func.max(CreditHistory.id)).all()if credit_os_result is not None or len(credit_os_result)>0:userIds=[]for r in credit_os_result:userIds.append(r.user_id)userCounterMap = user_client.getCounterName(userIds)return userCounterMap, credit_os_resultexcept Exception as e:print edef mark_payment_settled(userId,paymentId,totalAmount,repaymentDate):try:pendingSettlements = session.query(LoanHistory).filter_by(user_id=userId,payment_id=paymentId).all()if pendingSettlements is not None:amount=0for pendingSettlement in pendingSettlements:amount += pendingSettlement.amountif amount!=totalAmount:return False,"Amount mismatch for the particular payment id"else:loanObjs = []for pendingSettlement in pendingSettlements:loanObj = __loanHistoryObj(pendingSettlement.user_id, 1, pendingSettlement.payment_id, pendingSettlement.amount, CreditTxnType.PAID, pendingSettlement.loan_id,to_py_date(repaymentDate), pendingSettlement.invoiceNumber)loanObjs.append(loanObj)if process_loan_transaction(paymentId, userId, 1, loanObjs):return True,"Successfully settled payment"else:return False,"No payment to be settled."except:print traceback.print_exc()return False,"Some exception at the backend"def mark_payment_settled_partial(userId,paymentId,totalAmount,repaymentDate):try:pendingSettlements = session.query(LoanHistory).filter_by(user_id=userId,payment_id=paymentId).all()if pendingSettlements is not None:amount=0for pendingSettlement in pendingSettlements:amount += pendingSettlement.amountif amount!=totalAmount:return False,"Amount mismatch for the particular payment id"else:loanObjs = []for pendingSettlement in pendingSettlements:loanObj = __loanHistoryObj(pendingSettlement.user_id, 1, pendingSettlement.payment_id, pendingSettlement.amount, CreditTxnType.PAID, pendingSettlement.loan_id,datetime.datetime.strptime(repaymentDate, '%Y-%m-%d'), pendingSettlement.invoiceNumber)loanObjs.append(loanObj)process_loan_transaction(paymentId, userId, 1, loanObjs)else:return False,"No payment to be settled."except:print traceback.print_exc()def set_order_attribute_for_master_order_id(logisticsTransactionId, attributes):orders = get_group_orders_by_logistics_txn_id(logisticsTransactionId)for order in orders:for attribute in attributes :existingAttribute = Attribute.query.filter(Attribute.orderId == order.id).filter(Attribute.name == attribute.name).first()if existingAttribute:existingAttribute.value = attribute.valueelse :attr = Attribute()attr.orderId = order.idattr.name = attribute.nameattr.value = attribute.valuesession.commit()def update_master_order_awb(logisticsTransactionId, airwaybill_no):orders = get_group_orders_by_logistics_txn_id(logisticsTransactionId)shipmentAmount = 0shipmentWeight = 0shipmentLogisticsCost = 0shipmentCodCollectionCharges = 0for order in orders:order.airwaybill_no = airwaybill_noorder.tracking_id = airwaybill_noshipmentAmount = shipmentAmount + order.total_amountshipmentWeight = shipmentWeight + order.total_weightshipmentLogisticsCost = shipmentLogisticsCost + order.lineitems[0].logisticsCostshipmentCodCollectionCharges = shipmentCodCollectionCharges + order.lineitems[0].codCollectionChargesshipmentLogisticsCostObj = TShipmentLogisticsCostDetail()shipmentLogisticsCostObj.airwayBillNo = airwaybill_noshipmentLogisticsCostObj.logisticsTransactionId = logisticsTransactionIdshipmentLogisticsCostObj.shipmentAmount = shipmentAmountshipmentLogisticsCostObj.shipmentCodCollectionCharges = shipmentCodCollectionChargesshipmentLogisticsCostObj.shipmentLogsiticsCost = shipmentLogisticsCostshipmentLogisticsCostObj.shipmentWeight = shipmentWeightshipmentLogisticsCostDetails = []shipmentLogisticsCostDetails.append(shipmentLogisticsCostObj)add_or_update_shipment_logistics_cost_details(shipmentLogisticsCostDetails)return Truedef add_or_update_shipment_logistics_cost_details(shipmentLogisticsCostDetails):currentTime = datetime.datetime.now()for shipmentLogisticsCostDetail in shipmentLogisticsCostDetails:shipment_logisticsCostDetail = ShipmentLogisticsCostDetail.get_by(logisticsTransactionId=shipmentLogisticsCostDetail.logisticsTransactionId)if shipment_logisticsCostDetail:shipment_logisticsCostDetail.shipmentAmount = round(shipmentLogisticsCostDetail.shipmentAmount,2)shipment_logisticsCostDetail.shipmentWeight = round(shipmentLogisticsCostDetail.shipmentWeight,3)shipment_logisticsCostDetail.shipmentLogsiticsCost = round(shipmentLogisticsCostDetail.shipmentLogsiticsCost,2)shipment_logisticsCostDetail.shipmentCodCollectionCharges = round(shipmentLogisticsCostDetail.shipmentCodCollectionCharges,2)shipment_logisticsCostDetail.updatedAt = currentTimeshipment_logisticsCostDetail.airwayBillNo = shipmentLogisticsCostDetail.airwayBillNoelse:raise RuntimeError("Unable to add ShipmentLogisticsCostDetail.")session.commit()return Truedef logisticsProviderFinalCheck(ordersList):return ordersListdef __create_return_order_info(order, status, quantity=0):returnOrderInfo = ReturnOrderInfo()returnOrderInfo.orderId = order.idreturnOrderInfo.lineItemId = order.lineitems[0].idif quantity>0:returnOrderInfo.returnQuantity = quantityelse:returnOrderInfo.returnQuantity = order.lineitems[0].quantityreturnOrderInfo.createdAt = datetime.datetime.now()returnOrderInfo.returnStatus = statusreturnOrderInfo.masterOrderId = order.logisticsTransactionIdreturnOrderInfo.warehouse_id = order.warehouse_idsession.commit()return returnOrderInfodef create_return_order_info(returnInfo, order=None, itemCondition="DAMAGED"):returnOrderInfo = ReturnOrderInfo()returnOrderInfo.orderId = returnInfo.orderIdreturnOrderInfo.lineItemId = order.lineitems[0].idreturnOrderInfo.returnQuantity = returnInfo.returnQuantityreturnOrderInfo.createdAt = datetime.datetime.now()if itemCondition=="DAMAGED":returnOrderInfo.returnStatus = OrderStatus._VALUES_TO_NAMES[OrderStatus.RET_REQUEST_RECEIVED]else:returnOrderInfo.returnStatus = OrderStatus._VALUES_TO_NAMES[OrderStatus.DOA_REQUEST_RECEIVED]returnOrderInfo.masterOrderId = order.logisticsTransactionIdreturnOrderInfo.warehouse_id = order.warehouse_idreturnOrderInfo.returnAction = returnInfo.returnActionreturnOrderInfo.freebieItemId = order.freebieItemIdreturnOrderInfo.returnTxnResolutionStatus = ReturnTxnResolutionStatus._VALUES_TO_NAMES[ReturnTxnResolutionStatus.PENDING]session.commit()return returnOrderInfodef get_return_order_info(returnOrderId):returnOrder = ReturnOrderInfo.get_by(id=returnOrderId)if not returnOrder:return Nonereturn returnOrderdef refund_return_order(returnOrderInfo, attrList):returnOrder = ReturnOrderInfo.get_by(id=returnOrderInfo.id)if returnOrder.returnStatus not in (OrderStatus._VALUES_TO_NAMES[OrderStatus.DOA_CERT_VALID], OrderStatus._VALUES_TO_NAMES[OrderStatus.DOA_CERT_INVALID], OrderStatus._VALUES_TO_NAMES[OrderStatus.DOA_LOST_IN_TRANSIT],OrderStatus._VALUES_TO_NAMES[OrderStatus.DOA_RECEIVED_DAMAGED] ,OrderStatus._VALUES_TO_NAMES[OrderStatus.RET_LOST_IN_TRANSIT], OrderStatus._VALUES_TO_NAMES[OrderStatus.RET_PRODUCT_UNUSABLE], OrderStatus._VALUES_TO_NAMES[OrderStatus.RET_PRODUCT_USABLE],OrderStatus._VALUES_TO_NAMES[OrderStatus.RET_RECEIVED_DAMAGED]):print "************returnig false staus check"return Falseif returnOrder.returnAction == ReturnAction.REFUND:returnOrder.returnTxnResolutionStatus = ReturnTxnResolutionStatus._VALUES_TO_NAMES[ReturnTxnResolutionStatus.REFUND_IN_PROCESS]else:returnOrder.returnTxnResolutionStatus = ReturnTxnResolutionStatus._VALUES_TO_NAMES[ReturnTxnResolutionStatus.REPLACEMENT_ORDER_CREATED]detailsMap = {}if returnOrder.refundedAt or returnOrder.replacementOrderId:raise TransactionServiceException(145, "Refund/Replacemet already in Process for this return order")if returnOrder.receivedQuantity != returnOrder.returnQuantity:raise TransactionServiceException(145, "Quantity mismatch Return vs Received")detailsMap['RefundReason'] = returnOrderInfo.refundReasondetailsMap['RefundType'] = returnOrderInfo.refundTypedetailsMap['RefundedBy'] = returnOrderInfo.refundedBydetailsMap['RefundAmount'] = returnOrderInfo.refundAmountdetailsMap['RefundDescription'] = returnOrderInfo.refundDescriptionprint detailsMapprint "*************************8"if(not __process_return_order(returnOrder, detailsMap)):raise TransactionServiceException(145, "Issue in __process_return_order")returnOrder.processedAt = datetime.datetime.now()__markReturnTransactionAsProcessed(returnOrder.returnTransaction_id)set_order_attributes(returnOrder.orderId, attrList)return Truedef __markReturnTransactionAsProcessed(returnTransactionId):returnTransaction = ReturnTransaction.get_by(id=returnTransactionId)if returnTransaction is None:raise TransactionServiceException(101, "No Return Transaction Found")unprocessedOrders = []for retOrder in returnTransaction.returnOrders:if retOrder.reshippedAt is None and retOrder.refundedAt is None:unprocessedOrders.append(retOrder)if len(unprocessedOrders) == 0:returnTransaction.processedAt = datetime.datetime.now()returnTransaction.status = ReturnTransactionStatus._VALUES_TO_NAMES[ReturnTransactionStatus.PROCESSED]session.commit()def get_return_orders_info_map(order_ids=None, statuses=None):returnOrdersInfoQuery = ReturnOrderInfo.queryif order_ids is not None and len(order_ids)>0:returnOrdersInfoQuery = returnOrdersInfoQuery.filter(ReturnOrderInfo.orderId.in_(tuple(order_ids)))if statuses is not None:returnOrdersInfoQuery = returnOrdersInfoQuery.filter(ReturnOrderInfo.returnStatus.in_(tuple(statuses)))allReturnOrdersList = returnOrdersInfoQuery.all()returnOrdersInfoMap = {}for returnOrder in allReturnOrdersList:if returnOrdersInfoMap.has_key(returnOrder.orderId):returnList = returnOrdersInfoMap.get(returnOrder.orderId)returnList.append(returnOrder)returnOrdersInfoMap[returnOrder.orderId] = returnListelse:returnList = []returnList.append(returnOrder)returnOrdersInfoMap[returnOrder.orderId] = returnListreturn returnOrdersInfoMapdef update_return_order_info(returnInfo):try:returnOrderInfo = get_return_order_info(returnInfo.id)returnOrderInfo.returnStatus = returnInfo.returnStatusif returnInfo.processedAt:returnOrderInfo.processedAt = to_py_date(returnInfo.processedAt)if returnInfo.reshippedAt:returnOrderInfo.reshippedAt = to_py_date(returnInfo.reshippedAt)if returnInfo.receivedAt:returnOrderInfo.receivedAt = to_py_date(returnInfo.receivedAt)if returnInfo.authorizedAt:returnOrderInfo.authorizedAt = to_py_date(returnInfo.authorizedAt)if returnInfo.refundAmount:returnOrderInfo.refundAmount = returnInfo.refundAmountif returnInfo.refundReason:returnOrderInfo.refundReason = returnInfo.refundReasonif returnInfo.refundedAt:returnOrderInfo.refundedAt = to_py_date(returnInfo.refundedAt)if returnInfo.refundedBy:returnOrderInfo.refundedBy = returnInfo.refundedByif returnInfo.refundType:returnOrderInfo.refundType = returnInfo.refundTypeif returnInfo.refundDescription:returnOrderInfo.refundDescription = returnInfo.refundDescriptionif returnInfo.logisticsRequestId:returnOrderInfo.logisticsRequestId = returnInfo.logisticsRequestIdif returnOrderInfo.shippingType != returnInfo.shippingType:returnOrderInfo.shippingType = returnInfo.shippingTypeif returnOrderInfo.replacementOrderId and returnInfo.shippingType:replacementorder = get_order(returnOrderInfo.replacementOrderId)replacementorder.promised_shipping_time = Nonereplacementorder.promised_delivery_time = Nonereplacementorder.transaction = Nonereplacementorder.expected_delivery_time = Nonereplacementorder.expected_shipping_time = Noneif returnInfo.replacementOrderId:returnOrderInfo.replacementOrderId = returnInfo.replacementOrderIdif returnOrderInfo.returnPickupType != returnInfo.returnPickupType:if returnOrderInfo.logisticsRequestId:returnpickupRequest = ReturnPickupRequest.get_by(id=returnOrderInfo.logisticsRequestId)if returnpickupRequest.pickupStatus in ['PICKUP_REQUESTED','PENDING']:returnOrderInfo.returnPickupType = returnInfo.returnPickupTypeelse:returnOrderInfo.returnPickupType = returnInfo.returnPickupTypeelse:return Falseif returnOrderInfo.returnAction != returnInfo.returnAction:returnOrderInfo.returnAction = returnInfo.returnActionsession.commit()return Trueexcept:return Falsedef bulk_update_return_order_info(orderReturnInfosMap):responseMap = {}for orderId, returnOrdersList in orderReturnInfosMap.items():for returnOrder in returnOrdersList:response = update_return_order_info(returnOrder)responseMap[orderId] = responsereturn responseMapdef get_return_orders_as_per_warehouse(warehouseId):all_return_orders_as_per_warehouse = ReturnOrderInfo.query.filter(ReturnOrderInfo.processedAt==None).filter(ReturnOrderInfo.warehouse_id <= warehouseId).all()if all_return_orders_as_per_warehouse is None:all_return_orders_as_per_warehouse = []return all_return_orders_as_per_warehousedef create_return_transaction(returnTransaction, itemCondition, overrideWarranty):t_orders = returnTransaction.returnOrdersif not t_orders:raise TransactionServiceException(101, "Return Orders missing from the transaction")returnOrdersMap = {}for tOrder in t_orders:returnOrdersMap[tOrder.orderId] = tOrder.returnQuantityif validate_return_transaction(returnTransaction.customer_id, returnOrdersMap, itemCondition, overrideWarranty):returnTxn = ReturnTransaction()returnTxn.customer_id = returnTransaction.customer_idreturnTxn.status = ReturnTransactionStatus._VALUES_TO_NAMES[ReturnTransactionStatus.INITIATED]returnTxn.customer_email = returnTransaction.customer_emailreturnTxn.customer_name = returnTransaction.customer_namereturnTxn.createdAt = datetime.datetime.now()returnTxn.address_id = returnTransaction.address_idreturnTxn.customerAddress = returnTransaction.customerAddressreturnTxn.customerCity = returnTransaction.customerCityreturnTxn.customerPhone = returnTransaction.customerPhonereturnTxn.customerState = returnTransaction.customerStatereturnTxn.pincode = returnTransaction.pincodefor t_order in t_orders:order = get_order(t_order.orderId)returnOrder = create_return_order_info(t_order, order, itemCondition)returnOrder.returnTransaction = returnTxnlineitem = order.lineitems[0]lineitem.returnQty = lineitem.returnQty + returnOrder.returnQuantityorder.status = OrderStatus.PARTIAL_RETURN_IN_PROCESSorder.statusDescription = "Partial Return In Process"crmServiceClient = CRMClient().get_client()ticket =Ticket()activity = Activity()description = "Creating Ticket for return requested by customer:- " + str(returnTransaction.customer_name) + " Return Transaction Id:- "+ str(returnTxn.id)ticket.creatorId = 1ticket.assigneeId = 34ticket.category = TicketCategory.RETURN_FORMticket.priority = TicketPriority.HIGHticket.status = TicketStatus.OPENticket.description = descriptionticket.orderId = order.idactivity.creatorId = 1activity.ticketAssigneeId = ticket.assigneeIdactivity.type = ActivityType.OTHERactivity.description = descriptionactivity.ticketCategory = ticket.categoryactivity.ticketDescription = ticket.descriptionactivity.ticketPriority = ticket.priorityactivity.ticketStatus = ticket.statusticket.customerId= returnTransaction.customer_idticket.customerEmailId = returnTransaction.customer_emailticket.customerMobileNumber = returnTransaction.customerPhoneticket.customerName = returnTransaction.customer_nameactivity.customerId = ticket.customerIdactivity.customerEmailId = returnTransaction.customer_emailactivity.customerMobileNumber = returnTransaction.customerPhoneactivity.customerName = returnTransaction.customer_namereturnTxn.ticketId = crmServiceClient.insertTicket(ticket, activity)session.commit()return returnTxnreturn ReturnTransaction()def get_return_transactions_for_customer(statusList, customerMobile, customerEmail, returnTransactionId, customer_id):query = ReturnTransaction.queryif statusList is not None and len(statusList) >0:statuses = []for status in statusList:statuses.append(ReturnTransactionStatus._VALUES_TO_NAMES[status])query = query.filter(ReturnTransaction.status.in_(tuple(statuses)))if customer_id:query = query.filter(ReturnTransaction.customer_id == customer_id)if customerMobile:query = query.filter(ReturnTransaction.customerPhone == customerMobile)if customerEmail:query = query.filter(ReturnTransaction.customer_email == customerEmail)return query.all()def get_return_transaction(transaction_id):transaction = ReturnTransaction.get_by(id=transaction_id)if not transaction:raise TransactionServiceException(108, "no such transaction")return transactiondef get_return_orders_for_return_transaction(returnTransactionId):returnOrders = ReturnOrderInfo.query.filter_by(returnTransactionId=returnTransactionId).all()if not returnOrders:raise TransactionServiceException(101, "No return order for the transaction")return returnOrdersdef __process_return_order(returnOrder, returnOrderAttrMap):if returnOrder.returnAction:if returnOrder.refundedAt:raise TransactionServiceException(145, "Refund already in Process for this return order")refundReason = returnOrderAttrMap.get('RefundReason')refundType = returnOrderAttrMap.get('RefundType')refundedBy = returnOrderAttrMap.get('RefundedBy')refundAmount = returnOrderAttrMap.get('RefundAmount')order = get_order(returnOrder.orderId)status_transition = {}if order.cod:logging.info("Refunding COD order with status " + str(returnOrder.returnStatus))else:logging.info("Refunding Prepaid order with status " + str(returnOrder.returnStatus))status_transition = {"LOST_IN_TRANSIT" : "LOST_IN_TRANSIT_REFUNDED","DOA_CERT_INVALID" : "DOA_INVALID_REFUNDED","DOA_CERT_VALID" : "DOA_VALID_REFUNDED","DOA_RECEIVED_DAMAGED" : "DOA_REFUNDED_RCVD_DAMAGED","DOA_LOST_IN_TRANSIT" : "DOA_REFUNDED_LOST_IN_TRANSIT","RET_PRODUCT_UNUSABLE" : "RET_PRODUCT_UNUSABLE_REFUNDED","RET_PRODUCT_USABLE" : "RET_PRODUCT_USABLE_REFUNDED","RET_RECEIVED_DAMAGED" : "RET_REFUNDED_RCVD_DAMAGED","RET_LOST_IN_TRANSIT" : "RET_REFUNDED_LOST_IN_TRANSIT"}if returnOrder.returnStatus in status_transition.keys():returnOrder.returnStatus = status_transition[returnOrder.returnStatus]elif returnOrder.returnPickupType in [ReturnPickupType.LATER, ReturnPickupType.NOT_REQUIRED]:if returnOrder.returnPickupType == ReturnPickupType.LATER:returnOrder.refundDescription = "Pickup will be processed Later. Refund in Process. It takes 7-10 working days to be in actual credit."else:returnOrder.refundDescription = "No Pickup Required for this item. Refund in Process. It takes 7-10 working days to be in actual credit."else:raise TransactionServiceException(114, "This order can't be refunded")__create_refund(order, refundAmount, 'Refunded against #{0}, {1}pc(s)'.format(order.id, returnOrder.receivedQuantity))returnOrder.refundedAt = datetime.datetime.now()returnOrder.refundedBy = refundedByreturnOrder.refundReason = refundReasonreturnOrder.refundAmount = refundAmountreturnOrder.refundType = refundTypesession.commit()return Trueelse:alreadyReshipped = Falseif returnOrder.replacementOrderId:alreadyReshipped = Trueif returnOrder.returnStatus == OrderStatus._VALUES_TO_NAMES[OrderStatus.LOST_IN_TRANSIT]:returnOrder.returnStatus = OrderStatus._VALUES_TO_NAMES[OrderStatus.LOST_IN_TRANSIT_RESHIPPED]if not alreadyReshipped:order = get_order(returnOrder.orderId)new_order = __clone_order(order, False, order.cod)elif returnOrder.returnStatus == OrderStatus._VALUES_TO_NAMES[OrderStatus.DOA_CERT_INVALID]:returnOrder.returnStatus = OrderStatus._VALUES_TO_NAMES[OrderStatus.DOA_INVALID_RESHIPPED]if not alreadyReshipped:order = get_order(returnOrder.orderId)new_order = __clone_order(order, True, False)__scan_for_reship_order(returnOrder.orderId, new_order, returnOrder)elif returnOrder.returnStatus == OrderStatus._VALUES_TO_NAMES[OrderStatus.DOA_CERT_VALID]:returnOrder.returnStatus = OrderStatus._VALUES_TO_NAMES[OrderStatus.DOA_VALID_RESHIPPED]if not alreadyReshipped:order = get_order(returnOrder.orderId)new_order = __clone_order(order, False, False)elif returnOrder.returnStatus == OrderStatus._VALUES_TO_NAMES[OrderStatus.DOA_RECEIVED_DAMAGED]:returnOrder.returnStatus = OrderStatus._VALUES_TO_NAMES[OrderStatus.DOA_RESHIPPED_RCVD_DAMAGED]if not alreadyReshipped:order = get_order(returnOrder.orderId)new_order = __clone_order(order, False, False)elif returnOrder.returnStatus == OrderStatus._VALUES_TO_NAMES[OrderStatus.DOA_LOST_IN_TRANSIT]:returnOrder.returnStatus = OrderStatus._VALUES_TO_NAMES[OrderStatus.DOA_RESHIPPED_LOST_IN_TRANSIT]if not alreadyReshipped:order = get_order(returnOrder.orderId)new_order = __clone_order(order, False, False)elif returnOrder.returnStatus == OrderStatus._VALUES_TO_NAMES[OrderStatus.RET_PRODUCT_USABLE]:returnOrder.returnStatus = OrderStatus._VALUES_TO_NAMES[OrderStatus.RET_PRODUCT_USABLE_RESHIPPED]if not alreadyReshipped:order = get_order(returnOrder.orderId)new_order = __clone_order(order, False, False)elif returnOrder.returnStatus == OrderStatus._VALUES_TO_NAMES[OrderStatus.RET_PRODUCT_UNUSABLE]:returnOrder.returnStatus = OrderStatus._VALUES_TO_NAMES[OrderStatus.RET_PRODUCT_UNUSABLE_RESHIPPED]if not alreadyReshipped:order = get_order(returnOrder.orderId)new_order = __clone_order(order, False, False)elif returnOrder.returnStatus == OrderStatus._VALUES_TO_NAMES[OrderStatus.RET_RECEIVED_DAMAGED]:returnOrder.returnStatus = OrderStatus._VALUES_TO_NAMES[OrderStatus.RET_RESHIPPED_RCVD_DAMAGED]if not alreadyReshipped:order = get_order(returnOrder.orderId)new_order = __clone_order(order, False, False)elif returnOrder.returnStatus == OrderStatus._VALUES_TO_NAMES[OrderStatus.RET_LOST_IN_TRANSIT]:returnOrder.returnStatus = OrderStatus._VALUES_TO_NAMES[OrderStatus.RET_RESHIPPED_LOST_IN_TRANSIT]if not alreadyReshipped:order = get_order(returnOrder.orderId)new_order = __clone_order(order, False, False)elif returnOrder.returnPickupType in [ReturnPickupType.LATER, ReturnPickupType.NOT_REQUIRED]:if not alreadyReshipped:order = get_order(returnOrder.orderId)new_order = __clone_order(order, False, False)returnOrder.refundDescription = "Replacement Order has been created."else:return Falseif not alreadyReshipped:returnOrder.replacementOrderId = new_order.idreturnOrder.reshippedAt = datetime.datetime.now()orderQty = returnOrder.returnQuantityif returnOrder.returnPickupType not in [ReturnPickupType.LATER, ReturnPickupType.NOT_REQUIRED]:orderQty = returnOrder.receivedQuantitynew_order.lineitems[0].quantity = orderQtynew_order.lineitems[0].total_price = new_order.lineitems[0].unit_price * orderQtynew_order.lineitems[0].total_weight = new_order.lineitems[0].unit_weight * orderQtynew_order.total_amount = new_order.lineitems[0].unit_price * orderQtynew_order.total_weight = new_order.lineitems[0].unit_weight * orderQtyif returnOrder.shippingType:new_order.transaction = Nonenew_order.promised_shipping_time = Nonenew_order.expected_shipping_time = Nonenew_order.promised_delivery_time = Nonenew_order.expected_delivery_time = Nonesession.commit()return Trueelse:session.commit()return Truedef communicate_pickup_details_to_customer(returnPickupRequest, returnOrders):returnTxn = returnOrders[0].returnTransactionsubject = 'Pickup details for '+str(returnTxn.id)filename = "/PickupDetails/" + str(returnPickupRequest.pickupRequestNo) +".pdf"try:inventory_client = InventoryClient().get_client()warehouse = inventory_client.getWarehouse(returnOrders[0].warehouse_id)logistics_client = LogisticsClient().get_client()provider = logistics_client.getProvider(returnPickupRequest.logisticsProviderId)provider_name = provider.nameto_addr = returnTxn.customer_emailpromised_pickup_time = returnPickupRequest.promised_pickup_timestamp.date().strftime("%d-%B-%Y (%A)")customer_address = returnTxn.customer_name +"\n" + returnTxn.customerAddress +"\n"customer_address = customer_address + returnTxn.customerCity + "\n"customer_address = customer_address + returnTxn.customerState + "\n"customer_address = customer_address + "PIN: "+returnTxn.pincode + "\n"customer_address = customer_address + "Phone: "+returnTxn.customerPhoneraw_message = '''Dear %(customer_name)s,Would like to inform you that we have instructed %(provider_name)s to pick up the material from the below mentioned address on or before %(date)s. %(provider_name)s pickup request number is %(pickup_request_no)s.'Take a printout of the attachment in this mail which contains the delivery address and paste it on the packed parcel. Kindly keep the parcel ready.Pickup will happen from the below mentioned address:-%(customer_address)sDo let us know in case of any concernsThanks & Regards%(source_name)s Team'''message = dedent(raw_message) % {'customer_name' : returnTxn.customer_name,'order_id' : returnTxn.id,'provider_name' : provider_name,'date': promised_pickup_time,'pickup_request_no' : returnPickupRequest.pickupRequestNo,'customer_address' : customer_address,'source_name' : source_name}print message__generate_return_transaction_invoice(returnOrders, warehouse, provider, filename)mail(help_user, help_password, [to_addr], subject, message, [get_attachment_part(filename)])session.commit()return Trueexcept Exception as e:print sys.exc_info()traceback.print_tb(sys.exc_info()[2])return Falsefinally:if os.path.exists(filename):os.remove(filename)def __communicate_customer_for_closed_transaction(returnTransaction):passdef change_return_transaction_status(returnTransactionId, new_status, returnOrdersIds=None, returnOrdersAttrMap=None):returnTransaction = ReturnTransaction.get_by(id=returnTransactionId)if returnTransaction is None:raise TransactionServiceException(101, "No Return Transaction Found")if new_status == ReturnTransactionStatus.AUTHORIZED:returnTransaction.authorizedAt = datetime.datetime.now()for returnOrder in returnTransaction.returnOrders:if returnOrder.returnStatus == OrderStatus._VALUES_TO_NAMES[OrderStatus.RET_REQUEST_RECEIVED]:returnOrder.returnStatus = OrderStatus._VALUES_TO_NAMES[OrderStatus.RET_REQUEST_AUTHORIZED]if returnOrder.returnStatus == OrderStatus._VALUES_TO_NAMES[OrderStatus.DOA_REQUEST_RECEIVED]:returnOrder.returnStatus = OrderStatus._VALUES_TO_NAMES[OrderStatus.DOA_REQUEST_AUTHORIZED]returnTransaction.status = ReturnTransactionStatus._VALUES_TO_NAMES[new_status]elif new_status == ReturnTransactionStatus.INPROCESS:for returnOrder in returnTransaction.returnOrders:returnOrder.returnTxnResolutionStatus = ReturnTxnResolutionStatus._VALUES_TO_NAMES[ReturnTxnResolutionStatus.AWAITING_PICKUP]if returnOrder.returnPickupType == ReturnPickupType.NOT_REQUIRED:passelse:if returnOrder.returnStatus == OrderStatus._VALUES_TO_NAMES[OrderStatus.RET_REQUEST_AUTHORIZED]:returnOrder.returnStatus = OrderStatus._VALUES_TO_NAMES[OrderStatus.RET_PICKUP_REQUEST_RAISED]if returnOrder.returnStatus == OrderStatus._VALUES_TO_NAMES[OrderStatus.DOA_REQUEST_AUTHORIZED]:returnOrder.returnStatus = OrderStatus._VALUES_TO_NAMES[OrderStatus.DOA_PICKUP_REQUEST_RAISED]returnTransaction.status = ReturnTransactionStatus._VALUES_TO_NAMES[new_status]returnTransaction.status = ReturnTransactionStatus._VALUES_TO_NAMES[new_status]elif new_status == ReturnTransactionStatus.REJECTED:returnTransaction.processedAt = datetime.datetime.now()for returnOrder in returnTransaction.returnOrders:returnOrder.returnTxnResolutionStatus = ReturnTxnResolutionStatus._VALUES_TO_NAMES[ReturnTxnResolutionStatus.CLOSED]if returnOrder.returnStatus == OrderStatus._VALUES_TO_NAMES[OrderStatus.RET_REQUEST_RECEIVED]:returnOrder.returnStatus = OrderStatus._VALUES_TO_NAMES[OrderStatus.REJECTED]if returnOrder.returnStatus == OrderStatus._VALUES_TO_NAMES[OrderStatus.DOA_REQUEST_RECEIVED]:returnOrder.returnStatus = OrderStatus._VALUES_TO_NAMES[OrderStatus.REJECTED]returnTransaction.status = ReturnTransactionStatus._VALUES_TO_NAMES[new_status]elif new_status == ReturnTransactionStatus.PROCESSED:if returnOrdersIds and len(returnOrdersIds)>0:unprocessedOrders = []for retOrder in returnTransaction.returnOrders:if retOrder.reshippedAt is None or retOrder.refundedAt is None:unprocessedOrders.append(retOrder)if len(returnOrdersIds) < len(returnTransaction.returnOrders):if len(returnOrdersIds) == len(unprocessedOrders):for ret_Order in unprocessedOrders:if ret_Order.returnAction == ReturnAction.REFUND:ret_Order.returnTxnResolutionStatus = ReturnTxnResolutionStatus._VALUES_TO_NAMES[ReturnTxnResolutionStatus.REFUND_IN_PROCESS]else:ret_Order.returnTxnResolutionStatus = ReturnTxnResolutionStatus._VALUES_TO_NAMES[ReturnTxnResolutionStatus.REPLACEMENT_ORDER_CREATED]returnTransaction.processedAt = datetime.datetime.now()returnTransaction.status = ReturnTransactionStatus._VALUES_TO_NAMES[new_status]else:for ret_Order in returnTransaction.returnOrders:if ret_Order.returnAction == ReturnAction.REFUND:ret_Order.returnTxnResolutionStatus = ReturnTxnResolutionStatus._VALUES_TO_NAMES[ReturnTxnResolutionStatus.REFUND_IN_PROCESS]else:ret_Order.returnTxnResolutionStatus = ReturnTxnResolutionStatus._VALUES_TO_NAMES[ReturnTxnResolutionStatus.REPLACEMENT_ORDER_CREATED]returnTransaction.processedAt = datetime.datetime.now()returnTransaction.status = ReturnTransactionStatus._VALUES_TO_NAMES[new_status]for returnOrderId in returnOrdersIds:__process_return_order(get_return_order_info(returnOrderId), returnOrdersAttrMap.get(returnOrderId))elif new_status == ReturnTransactionStatus.COMPLETED:mark_return_transaction_complete(returnTransaction.id)elif new_status == ReturnTransactionStatus.CLOSED:if not returnTransaction.status == ReturnTransactionStatus._VALUES_TO_NAMES[ReturnTransactionStatus.COMPLETED]:raisereturnTransaction.closedAt = datetime.datetime.now()for ret_Order in returnTransaction.returnOrders:ret_Order.returnTxnResolutionStatus = ReturnTxnResolutionStatus._VALUES_TO_NAMES[ReturnTxnResolutionStatus.CLOSED]__communicate_customer_for_closed_transaction(returnTransaction)returnTransaction.status = ReturnTransactionStatus._VALUES_TO_NAMES[new_status]session.commit()return Truedef create_return_pickup_request(returnOrderIds):returnPickupRequest = ReturnPickupRequest()returnPickupRequest.pickupStatus = ReturnTxnPickupStatus._VALUES_TO_NAMES[ReturnTxnPickupStatus.PENDING]if len(returnOrderIds) > 0:for returnOrderId in returnOrderIds:returnOrder = get_return_order_info(returnOrderId)returnOrder.logisticsRequestId = returnPickupRequest.idsession.commit()return returnPickupRequest.idreturn 0def update_return_pickup_request(returnPickupRequest):print returnPickupRequesttry:returnPickupReq = ReturnPickupRequest.get_by(id=returnPickupRequest.id)if returnPickupRequest.pickupStatus == ReturnTxnPickupStatus.PICKUP_REQUESTED:returnPickupReq.pickupStatus = ReturnTxnPickupStatus._VALUES_TO_NAMES[returnPickupRequest.pickupStatus]if returnPickupRequest.pickupStatus == ReturnTxnPickupStatus.PICKUP_CONFIRMED:returnPickupReq.logisticsProviderId = returnPickupRequest.logisticsProviderIdreturnPickupReq.pickupRequestNo = returnPickupRequest.pickupRequestNoreturnPickupReq.confirmedAt = datetime.datetime.now()returnPickupReq.pickupStatus = ReturnTxnPickupStatus._VALUES_TO_NAMES[returnPickupRequest.pickupStatus]for returnOrder in ReturnOrderInfo.query.filter(ReturnOrderInfo.logisticsRequestId==returnPickupRequest.id).all():if returnOrder.returnStatus == OrderStatus._VALUES_TO_NAMES[OrderStatus.DOA_PICKUP_REQUEST_RAISED]:returnOrder.returnStatus = OrderStatus._VALUES_TO_NAMES[OrderStatus.DOA_PICKUP_CONFIRMED]else:returnOrder.returnStatus = OrderStatus._VALUES_TO_NAMES[OrderStatus.RET_PICKUP_CONFIRMED]if returnPickupRequest.pickupStatus == ReturnTxnPickupStatus.PICKUP_SCHEDULED:returnPickupReq.pickupStatus = ReturnTxnPickupStatus._VALUES_TO_NAMES[returnPickupRequest.pickupStatus]returnPickupReq.promised_pickup_timestamp = to_py_date(returnPickupRequest.promised_pickup_timestamp)returnOrdersMap = {}returnOrders = ReturnOrderInfo.query.filter(ReturnOrderInfo.logisticsRequestId==returnPickupRequest.id).all()for returnOrder in returnOrders:returnTxn = returnOrders[0].returnTransactionif returnOrdersMap.has_key(returnTxn.address_id):retOrders = returnOrdersMap.get(returnTxn.address_id)retOrders.append(returnOrder)returnOrdersMap[returnTxn.address_id] = retOrderselse:retOrders = []retOrders.append(returnOrder)returnOrdersMap[returnTxn.address_id] = retOrdersfor returnOrdersList in returnOrdersMap.values():try:communicate_pickup_details_to_customer(returnPickupReq, returnOrdersList)except:print "Customer Communication Failed for the pickup Information"if returnPickupRequest.pickupStatus == ReturnTxnPickupStatus.PICKUP_IN_TRANSIT:returnPickupReq.pickedUpAt = to_py_date(returnPickupRequest.pickedUpAt)returnPickupReq.pickupStatus = ReturnTxnPickupStatus._VALUES_TO_NAMES[ReturnTxnPickupStatus.PICKUP_IN_TRANSIT]for returnOrder in ReturnOrderInfo.query.filter(ReturnOrderInfo.logisticsRequestId==returnPickupRequest.id).all():if returnOrder.returnStatus == OrderStatus._VALUES_TO_NAMES[OrderStatus.DOA_PICKUP_CONFIRMED]:returnOrder.returnStatus = OrderStatus._VALUES_TO_NAMES[OrderStatus.DOA_RETURN_IN_TRANSIT]else:returnOrder.returnStatus = OrderStatus._VALUES_TO_NAMES[OrderStatus.RET_RETURN_IN_TRANSIT]if returnPickupRequest.pickupStatus == ReturnTxnPickupStatus.PICKUP_RECEIVED:returnPickupReq.pickupStatus = ReturnTxnPickupStatus._VALUES_TO_NAMES[ReturnTxnPickupStatus.PICKUP_RECEIVED]for returnOrder in ReturnOrderInfo.query.filter(ReturnOrderInfo.logisticsRequestId==returnPickupRequest.id).all():if returnOrder.returnStatus not in (OrderStatus._VALUES_TO_NAMES[OrderStatus.DOA_CERT_VALID], OrderStatus._VALUES_TO_NAMES[OrderStatus.DOA_CERT_INVALID], OrderStatus._VALUES_TO_NAMES[OrderStatus.DOA_LOST_IN_TRANSIT], OrderStatus._VALUES_TO_NAMES[OrderStatus.DOA_RECEIVED_DAMAGED],OrderStatus._VALUES_TO_NAMES[OrderStatus.DOA_CERT_VALID],OrderStatus._VALUES_TO_NAMES[OrderStatus.RET_LOST_IN_TRANSIT], OrderStatus._VALUES_TO_NAMES[OrderStatus.RET_PRODUCT_UNUSABLE], OrderStatus._VALUES_TO_NAMES[OrderStatus.RET_PRODUCT_USABLE], OrderStatus._VALUES_TO_NAMES[OrderStatus.RET_RECEIVED_DAMAGED]):return FalsereturnOrder.returnTxnResolutionStatus = ReturnTxnResolutionStatus._VALUES_TO_NAMES[ReturnTxnResolutionStatus.QUALITY_CHECK]session.commit()return Trueexcept:traceback.print_exc()return Falsedef receive_return_pickup(returnOrdersMap, req_id):#returnPickupReq = ReturnPickupRequest.get_by(id=req_id)#returnOrders = ReturnOrderInfo.query.filter(ReturnOrderInfo.logisticsRequestId==req_id).all()#if len(returnOrders)!=len(returnOrdersMap.keys()):# raise TransactionServiceException(101, "All Returns Orders Information Missing. Please Fill All Orders Info")print "returnOrdersMap", returnOrdersMapfor returnOrderId in returnOrdersMap.iterkeys():returnOrder = ReturnOrderInfo.get_by(id=returnOrderId)if returnOrder is None:raise TransactionServiceException(101, "Return order missing")returnOrderDetails = returnOrdersMap.get(returnOrder.id)receiveCondition = ReceivedReturnType._NAMES_TO_VALUES[returnOrderDetails.get('ReceiveCondition')]quantity = int(returnOrderDetails.get('Quantity'))returnOrder.receivedReturnType = receiveConditionreturnOrder.receivedReturnType = receiveConditionif returnOrder.returnStatus in [OrderStatus._VALUES_TO_NAMES[OrderStatus.DOA_PICKUP_CONFIRMED], OrderStatus._VALUES_TO_NAMES[OrderStatus.DOA_RETURN_IN_TRANSIT]]:if receiveCondition == ReceivedReturnType.PRESTINE:returnOrder.returnStatus = OrderStatus._VALUES_TO_NAMES[OrderStatus.DOA_RECEIVED_PRESTINE]elif receiveCondition == ReceivedReturnType.DAMAGED:returnOrder.returnStatus = OrderStatus._VALUES_TO_NAMES[OrderStatus.DOA_RECEIVED_DAMAGED]elif receiveCondition == ReceivedReturnType.LOST_IN_TRANSIT:returnOrder.returnStatus = OrderStatus._VALUES_TO_NAMES[OrderStatus.DOA_LOST_IN_TRANSIT]returnOrder.receivedAt = datetime.datetime.now()returnOrder.receivedQuantity = quantityelif returnOrder.returnStatus in [OrderStatus._VALUES_TO_NAMES[OrderStatus.RET_PICKUP_CONFIRMED], OrderStatus._VALUES_TO_NAMES[OrderStatus.RET_RETURN_IN_TRANSIT]]:if receiveCondition == ReceivedReturnType.PRESTINE:returnOrder.returnStatus = OrderStatus._VALUES_TO_NAMES[OrderStatus.RET_RECEIVED_PRESTINE]elif receiveCondition == ReceivedReturnType.DAMAGED:returnOrder.returnStatus = OrderStatus._VALUES_TO_NAMES[OrderStatus.RET_RECEIVED_DAMAGED]elif receiveCondition == ReceivedReturnType.LOST_IN_TRANSIT:returnOrder.returnStatus = OrderStatus._VALUES_TO_NAMES[OrderStatus.RET_LOST_IN_TRANSIT]returnOrder.receivedAt = datetime.datetime.now()returnOrder.receivedQuantity = quantityelse:return FalsescanMap = {"RET_RECEIVED_PRESTINE" : ScanType.SALE_RET,"RET_RECEIVED_DAMAGED" : ScanType.SALE_RET_UNUSABLE,"RET_LOST_IN_TRANSIT" : ScanType.LOST_IN_TRANSIT,"DOA_RECEIVED_PRESTINE" : ScanType.DOA_IN,"DOA_RECEIVED_DAMAGED" : ScanType.DOA_IN,"DOA_LOST_IN_TRANSIT" : ScanType.LOST_IN_TRANSIT}inventoryClient = InventoryClient().get_client()warehouse = inventoryClient.getWarehouse(returnOrder.warehouse_id)warehouseClient = WarehouseClient().get_client()for returnOrderId in returnOrdersMap.iterkeys():returnOrder = ReturnOrderInfo.get_by(id=returnOrderId)returnOrderDetails = returnOrdersMap.get(returnOrder.id)warehouse = inventoryClient.getWarehouse(returnOrder.warehouse_id)serialNumbers = []if returnOrderDetails.has_key('SerialNumbers'):serialNumbersSplitted = returnOrderDetails.get('SerialNumbers').split(',')serialNumbers = []for t in serialNumbersSplitted:if t.strip() !="":serialNumbers.append(t.strip())scanFreebie = Falseif returnOrderDetails.has_key('ScanFreebie') and returnOrderDetails.get('ScanFreebie')=='yes':scanFreebie = Truequantity = int(returnOrderDetails.get('Quantity'))if warehouse is not None and warehouse.billingType == BillingType.OURS or warehouse.billingType == BillingType.OURS_EXTERNAL:if scanMap.has_key(returnOrder.returnStatus):scanType = scanMap[returnOrder.returnStatus]lineitem = returnOrder.lineitemreturn_qty = lineitem.returnQty - returnOrder.returnQuantity + quantitylineitem.returnQty = lineitem.returnQty - returnOrder.returnQuantity + quantityorder = get_order(returnOrder.orderId)if return_qty < order.lineitems[0].quantity:order.status = OrderStatus.PARTIAL_RETURNif return_qty == order.lineitems[0].quantity:order.status = OrderStatus.COMPLETE_RETURNif warehouse.billingType == BillingType.OURS or scanType != ScanType.SALE_RET:if lineitem.serial_number is not None:if serialNumbers is None or len(serialNumbers)==0 or len(serialNumbers)<quantity:return Falseelse:for serialNumber in serialNumbers:try:warehouseClient.scanSerializedItemForOrder(serialNumber, scanType, order.id, order.fulfilmentWarehouseId, 1, order.warehouse_id)except:warehouseClient = WarehouseClient().get_client()warehouseClient.scanSerializedItemForOrder(serialNumber, scanType, order.id, order.fulfilmentWarehouseId, 1, order.warehouse_id)else:try:warehouseClient.scanForOrder(None, scanType, quantity, order.id, order.fulfilmentWarehouseId, order.warehouse_id)except:warehouseClient = WarehouseClient().get_client()warehouseClient.scanForOrder(None, scanType, quantity, order.id, order.fulfilmentWarehouseId, order.warehouse_id)if warehouse.billingType == BillingType.OURS_EXTERNAL and scanType == ScanType.SALE_RET:try:warehouseClient.scanForOursExternalSaleReturn(order.id, lineitem.transfer_price)except:warehouseClient = WarehouseClient().get_client()warehouseClient.scanForOursExternalSaleReturn(order.id, lineitem.transfer_price)if scanFreebie:try:warehouseClient.scanfreebie(order.id, order.freebieItemId, 0, scanType)except:warehouseClient = WarehouseClient().get_client()warehouseClient.scanfreebie(order.id, order.freebieItemId, 0, scanType)isValid = returnOrderDetails.get('productUsable')if returnOrder.returnStatus == OrderStatus._VALUES_TO_NAMES[OrderStatus.DOA_RECEIVED_PRESTINE]:if isValid == "true":returnOrder.returnStatus = OrderStatus._VALUES_TO_NAMES[OrderStatus.DOA_CERT_VALID]else:returnOrder.returnStatus = OrderStatus._VALUES_TO_NAMES[OrderStatus.DOA_CERT_INVALID]elif returnOrder.returnStatus == OrderStatus._VALUES_TO_NAMES[OrderStatus.RET_RECEIVED_PRESTINE]:if isValid == "true":returnOrder.returnStatus = OrderStatus._VALUES_TO_NAMES[OrderStatus.RET_PRODUCT_USABLE]else:returnOrder.returnStatus = OrderStatus._VALUES_TO_NAMES[OrderStatus.RET_PRODUCT_UNUSABLE]session.commit()return Truedef validate_return_pickup(returnPickupId, returnOrdersMap):returnOrders = ReturnOrderInfo.query.filter(ReturnOrderInfo.logisticsRequestId==returnPickupId).all()if len(returnOrders)!=len(returnOrdersMap.keys()):raise TransactionServiceException(101, "All Returns Orders Information Missing. Please Fill All Orders Info")for returnOrder in returnOrders:if returnOrder.returnStatus != OrderStatus._VALUES_TO_NAMES[OrderStatus.DOA_RECEIVED_PRESTINE] and returnOrder.returnStatus != OrderStatus._VALUES_TO_NAMES[OrderStatus.RET_RECEIVED_PRESTINE]:return Falsefor returnOrder in returnOrders:isValid = returnOrdersMap.get(returnOrder.id)if returnOrder.returnStatus == OrderStatus._VALUES_TO_NAMES[OrderStatus.DOA_RECEIVED_PRESTINE]:if isValid:returnOrder.returnStatus = OrderStatus._VALUES_TO_NAMES[OrderStatus.DOA_CERT_VALID]else:returnOrder.returnStatus = OrderStatus._VALUES_TO_NAMES[OrderStatus.DOA_CERT_INVALID]else:if isValid:returnOrder.returnStatus = OrderStatus._VALUES_TO_NAMES[OrderStatus.RET_PRODUCT_USABLE]else:returnOrder.returnStatus = OrderStatus._VALUES_TO_NAMES[OrderStatus.RET_PRODUCT_UNUSABLE]session.commit()return Truedef process_return_pickup(returnPickupId, returnOrdersMap):returnOrders = ReturnOrderInfo.query.filter(ReturnOrderInfo.logisticsRequestId==returnPickupId).all()returnTxnIdOrdersMap = {}if len(returnOrders)!=len(returnOrdersMap.keys()):raise TransactionServiceException(101, "All Returns Orders Information Missing. Please Fill All Orders Info")for returnOrder in returnOrders:if returnTxnIdOrdersMap.has_key(returnOrder.returnTransaction.id):ordersList = returnTxnIdOrdersMap.get(returnOrder.returnTransaction.id)ordersList.append(returnOrder.id)returnTxnIdOrdersMap[returnOrder.returnTransaction.id] = ordersListelse:ordersList = []ordersList.append(returnOrder.id)returnTxnIdOrdersMap[returnOrder.returnTransaction.id] = ordersListfor returnTransactionId, returnOrdersIds in returnTxnIdOrdersMap.items():change_return_transaction_status(returnTransactionId, ReturnTransactionStatus.PROCESSED, returnOrdersIds, returnOrdersMap)session.commit()return Truedef mark_return_transaction_complete(returnTransactionId):returnTransaction = get_return_transaction(returnTransactionId)if returnTransaction.status == ReturnTransactionStatus._VALUES_TO_NAMES[ReturnTransactionStatus.COMPLETED]:raise TransactionServiceException(101, "Transaction Already completed")returnString = ''for returnOrder in returnTransaction.returnOrders:if returnOrder.processedAt is None:returnString = returnString + str(returnOrder.id)+":"+str(returnOrder.lineitem)+"|"if len(returnString) >0 :raise TransactionServiceException(140, "Unprocessed orders are: "+returnString)returnTransaction.status = ReturnTransactionStatus._VALUES_TO_NAMES[ReturnTransactionStatus.COMPLETED]session.commit()return Truedef refund_return_transaction_payment(returnOrdersMap, returnTransactionId):for returnOrderId, returnOrderAttrMap in returnOrdersMap.items():returnOrder = get_return_order_info(returnOrderId)if returnOrder.returnAction:returnOrder.processedAt = datetime.datetime.now()returnOrder.refundDescription = returnOrder.refundDescription + returnOrderAttrMap.get("RefundInfo")returnOrder.returnTxnResolutionStatus = ReturnTxnResolutionStatus._VALUES_TO_NAMES[ReturnTxnResolutionStatus.REFUND_DONE]else:returnOrder.processedAt = datetime.datetime.now()returnOrder.refundDescription = str(returnOrder.replacementOrderId) + " has been delivered now"returnOrder.returnTxnResolutionStatus = ReturnTxnResolutionStatus._VALUES_TO_NAMES[ReturnTxnResolutionStatus.REPLACEMENT_DONE]session.commit()def get_eligible_orders_for_return(customerId, itemCondition, overrideWarranty):query = session.query(Order).join((LineItem,Order.id==LineItem.order_id)).filter(Order.customer_id==customerId).filter(Order.delivery_timestamp != None).filter(Order.status.in_(tuple([OrderStatus.DELIVERY_SUCCESS,OrderStatus.PARTIAL_RETURN,OrderStatus.PARTIAL_RETURN_IN_PROCESS]))).filter(LineItem.quantity-LineItem.returnQty>0)if not overrideWarranty and itemCondition is not None:if itemCondition == 'DAMAGED':query = query.filter(LineItem.damaged_expiry_timestamp > datetime.datetime.now())elif itemCondition == 'DEFECTIVE':query = query.filter(LineItem.warranty_expiry_timestamp > datetime.datetime.now())orders = query.order_by(desc(Order.delivery_timestamp)).all()return ordersdef get_eligible_return_orders_for_pickup(customerId):return session.query(ReturnOrderInfo).join((ReturnTransaction,ReturnOrderInfo.returnTransaction_id==ReturnTransaction.id)).filter(ReturnTransaction.customer_id==customerId).filter(or_(ReturnOrderInfo.returnStatus==OrderStatus._VALUES_TO_NAMES[OrderStatus.RET_PICKUP_REQUEST_RAISED], ReturnOrderInfo.returnStatus==OrderStatus._VALUES_TO_NAMES[OrderStatus.DOA_PICKUP_REQUEST_RAISED])).filter(ReturnOrderInfo.logisticsRequestId==None).all()def validate_return_transaction(customerId, returnOrdersMap, itemCondition, overrideWarranty):eligibleOrders = get_eligible_orders_for_return(customerId, itemCondition, overrideWarranty)ordersMap = {}for order in eligibleOrders:ordersMap[order.id] = order.lineitems[0].quantity - order.lineitems[0].returnQtyfor orderId, returnOrderQty in returnOrdersMap.items():if returnOrderQty > ordersMap.get(orderId):return Falsereturn Truedef get_return_pickup_request(returnPickupId):return ReturnPickupRequest.get_by(id=returnPickupId)def mark_return_not_required_orders_as_processed(t_returnOrderInfo):returnOrderInfo = ReturnOrderInfo.get_by(id=t_returnOrderInfo.id)if returnOrderInfo is None:raise TransactionServiceException(101, "No Return Order Found")if returnOrderInfo.returnPickupType == ReturnPickupType.NOT_REQUIRED:if returnOrderInfo.returnAction == ReturnAction.REPLACEMENT or t_returnOrderInfo.refundType!= RefundType.WALLET:raise TransactionServiceException(101, "Refund Type not Defined for return order:- "+str(returnOrderInfo.id))detailsMap = {}if returnOrderInfo.refundedAt :raise TransactionServiceException(145, "Refund already in Process for this return order")detailsMap['RefundReason'] = "As per Customer Request"detailsMap['RefundType'] = t_returnOrderInfo.refundTypedetailsMap['RefundedBy'] = t_returnOrderInfo.refundedBydetailsMap['RefundAmount'] = t_returnOrderInfo.refundAmountreturnOrderInfo.returnTxnResolutionStatus = ReturnTxnResolutionStatus._VALUES_TO_NAMES[ReturnTxnResolutionStatus.REFUND_IN_PROCESS]if(not __process_return_order(returnOrderInfo, detailsMap)):raise TransactionServiceException(145, "Issue in __process_return_order")returnOrderInfo.processedAt = datetime.datetime.now()returnOrderInfo.returnTxnResolutionStatus = ReturnTxnResolutionStatus._VALUES_TO_NAMES[ReturnTxnResolutionStatus.REFUND_DONE]session.commit()__markReturnTransactionAsProcessed(returnOrderInfo.returnTransaction_id)return Truedef get_all_return_orders_for_return_pickup_request(logisticsRequestId):return ReturnOrderInfo.query.filter(ReturnOrderInfo.logisticsRequestId==logisticsRequestId).all()def __clone_return_order(returnOrder, splitOrderQty):if returnOrder.returnQuantity <= splitOrderQty or splitOrderQty<=0:raise TransactionServiceException(101, "SplitQty canot be equal to or greater than parent return order returnQty")returnOrder.returnQuantity = returnOrder.returnQuantity - splitOrderQtynew_return_order = ReturnOrderInfo()new_return_order.returnTransaction = returnOrder.returnTransactionnew_return_order.masterOrderId = returnOrder.masterOrderIdnew_return_order.orderId = returnOrder.orderIdnew_return_order.lineItemId = returnOrder.lineItemIdnew_return_order.logisticsRequestId = returnOrder.logisticsRequestIdnew_return_order.returnQuantity = splitOrderQtynew_return_order.receivedQuantity = returnOrder.receivedQuantitynew_return_order.createdAt = returnOrder.createdAtnew_return_order.processedAt = returnOrder.processedAtnew_return_order.returnStatus = returnOrder.returnStatusnew_return_order.reshippedAt = returnOrder.reshippedAtnew_return_order.receivedAt = returnOrder.receivedAtnew_return_order.refundReason = returnOrder.refundReasonnew_return_order.refundedBy = returnOrder.refundedBynew_return_order.refundedAt = returnOrder.refundedAtnew_return_order.warehouse_id = returnOrder.warehouse_idnew_return_order.refundAmount = returnOrder.refundAmountnew_return_order.refundType = returnOrder.refundTypenew_return_order.refundDescription = returnOrder.refundDescriptionnew_return_order.returnPickupType = returnOrder.returnPickupTypenew_return_order.shippingType = returnOrder.shippingTypenew_return_order.replacementOrderId = returnOrder.replacementOrderIdnew_return_order.receivedReturnType = returnOrder.receivedReturnTypenew_return_order.freebieItemId = returnOrder.freebieItemIdnew_return_order.returnAction = returnOrder.returnActionnew_return_order.returnTxnResolutionStatus = returnOrder.returnTxnResolutionStatusnew_return_order.lineitem = returnOrder.lineitemnew_return_order.returnPickUpRequest = returnOrder.returnPickUpRequestreturn new_return_orderdef get_seller_info(sellerId):sellerInfo = SellerInfo()seller = Seller.get_by(id=sellerId)if seller is None:return Noneelse:sellerInfo.tin = seller.tinsellerInfo.gstin = seller.gstinsellerInfo.stateId = seller.state_idorg = Organisation.get_by(id=seller.organisation_id)if org is None:return Noneelse:sellerInfo.organisationName = org.namesellerInfo.regId = org.registered_idsellerInfo.registeredAddress = org.addressif org.type == 'company':sellerInfo.cinNumber = org.registered_idreturn sellerInfodef get_warehouse_address(addressId):address = WarehouseAddressMaster.get_by(id=addressId)return to_t_warehouse_address(address)def split_return_order_info(returnOrderId, splitOrderQty):returnOrder = ReturnOrderInfo.get_by(id=returnOrderId)if returnOrder is None:raise TransactionServiceException(101, "No Return Order is there with this Order Id")new_return_order = __clone_return_order(returnOrder, splitOrderQty)session.commit()return new_return_order#Seller would be used to get tin numberdef __get_seller(warehouse_id):#As of now we have hardcoded the company and#seller would be returned on basis warehouse and company#Seller changed to HSSPL. Effective Aug-1-2016 - Amit Gupta#New Organisation has been added to it.(sellerId,) = session.query(Seller.id).join((SellerWarehouse, Seller.id==SellerWarehouse.seller_id)).filter(SellerWarehouse.warehouse_id==warehouse_id).first()return sellerIddef add_shipment_delay(shipmentDelayDetail):returnList = []for delayObj in shipmentDelayDetail:order = get_order(delayObj.orderId)if order.status not in [OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.ACCEPTED]:returnList.append(delayObj.orderId)continuetry:result = add_delay_reason(delayObj.orderId, delayObj.delayReason, delayObj.delay, delayObj.delayReasonText)except:returnList.append(delayObj.orderId)continueif not result:returnList.append(delayObj.orderId)return returnList#Buyer can be anyone based on logicdef __get_buyer(warehouse_id):#As of now we have hardcoded the company and#seller would be returned on basis warehouse and companybuyerId=Noneresult = session.query(Seller.id).join((SellerWarehouse, Seller.id==SellerWarehouse.seller_id)).filter(SellerWarehouse.warehouse_id==warehouse_id).first()if result:buyerId = result[0]return buyerIddef get_buyer_by_warehouse(warehouse_id):buyerId = __get_buyer(warehouse_id)if buyerId is None:return NonesellerInfo = get_seller_info(buyerId)buyerInfo = BuyerInfo()buyerInfo.cinNumber = sellerInfo.cinNumberbuyerInfo.organisationName = sellerInfo.organisationNamebuyerInfo.regId = sellerInfo.regIdbuyerInfo.tin = sellerInfo.tinbuyerInfo.gstin = sellerInfo.gstinbuyerInfo.registeredAddress = sellerInfo.registeredAddressbuyerInfo.buyerId = buyerIdbuyerInfo.stateId = sellerInfo.stateIdaddressMapping = session.query(WarehouseAddressMaster).join((WarehouseAddressMapping,WarehouseAddressMapping.address_id==WarehouseAddressMaster.id)).filter(WarehouseAddressMapping.warehouse_id==warehouse_id).first()if addressMapping is not None:buyerInfo.addressId = addressMapping.idbuyerInfo.buyerAddress = to_t_warehouse_address(addressMapping)else:return Noneprint buyerInforeturn buyerInfodef get_cost_detail_for_logistics_txn_id(logisticsTxnId):logisticCostDetail= ShipmentLogisticsCostDetail.get_by(logisticsTransactionId=logisticsTxnId)if logisticCostDetail is None:raisereturn logisticCostDetail##Shipment Logistics cost should be added only during billingdef add_shipment_logistic_detail(shipmentLogisticsCostDetail):if shipmentLogisticsCostDetail.logisticsTransactionId is None or shipmentLogisticsCostDetail.packageDimensions is None:raise ValueError("Null fields logisticsTransactionId/packageDimensions")logisticCostDetail= ShipmentLogisticsCostDetail.get_by(logisticsTransactionId=shipmentLogisticsCostDetail.logisticsTransactionId)if logisticCostDetail is not None:logisticCostDetail.packageDimensions = shipmentLogisticsCostDetail.packageDimensionselse:d_ShipmentLogisticsCostDetail = ShipmentLogisticsCostDetail()d_ShipmentLogisticsCostDetail.logisticsTransactionId = shipmentLogisticsCostDetail.logisticsTransactionIdd_ShipmentLogisticsCostDetail.packageDimensions = shipmentLogisticsCostDetail.packageDimensionssession.commit()def create_payment(userId, txnId, gatewayId):total_payable_amount = calculate_payment_amount(txnId)gv_amount = 0.0wallet_amount = 0.0transaction = Transaction.get_by(id=txnId)for order in transaction.orders:gv_amount = gv_amount + order.gvAmountwallet_amount = wallet_amount + order.wallet_amountpayment_client = PaymentClient().get_client()if gv_amount > 0:paymentId = payment_client.createPayment(userId, gv_amount, gvGatewayId, txnId, False);payment_client.updatePaymentDetails(paymentId, "", "", "SUCCESS", "Payment Received", "", "", "", "", PaymentStatus.SUCCESS, "", None);if wallet_amount > 0:paymentId = payment_client.createPayment(userId, wallet_amount, walletGatewayId, txnId, False);if total_payable_amount > 0:paymentId = payment_client.createPayment(userId, total_payable_amount, gatewayId, txnId, False);return paymentIddef calculate_payment_amount(txnId):transaction = Transaction.get_by(id=txnId)miscCharges = MiscCharges.get_by(transaction_id = transaction.id)total_amount = 0.0for order in transaction.orders:if order.net_payable_amount is None:order.net_payable_amount = 0total_amount = total_amount + order.net_payable_amountif miscCharges and miscCharges.get(1) is not None:total_amount = total_amount + miscCharges.get(1)return total_amountdef get_billed_orders_for_manifest_gen(warehouse_id, logistics_provider_id, cod):orders = Order.query.filter(Order.warehouse_id == warehouse_id)\.filter(Order.status == OrderStatus.BILLED)\.filter(Order.logistics_provider_id == logistics_provider_id).all()shipmentMap = {}p_returnMap = {}c_returnMap = {}for order in orders:if shipmentMap.has_key(order.logisticsTransactionId):shipmentMap.get(order.logisticsTransactionId).append(order)else:shipmentMap[order.logisticsTransactionId] = [order]for k,v in shipmentMap.iteritems():validShipment = Truefor order in v:if order.cod and order.net_payable_amount > 0:validShipment = Falsebreakif validShipment:p_returnMap[k] = shipmentMap.get(k)else:c_returnMap[k] = shipmentMap.get(k)if cod:return c_returnMap.values()else:return p_returnMap.values()def __copy_order(order):copy = Order()copy.from_dict(order.to_dict())copy.id = Nonelineitem = LineItem()lineitem.from_dict(order.lineitems[0].to_dict())lineitem.id = Nonecopy.lineitems = [lineitem]return copydef register_rsa(userId, activation_code):pmsa = PMSA.get_by(code=activation_code)if pmsa is None:return Falsepmsa_agents = PMSA_Agents.get_by(userId = userId)if pmsa_agents is None:pmsa_agents = PMSA_Agents()pmsa_agents.userId = userIdpmsa_agents.pmsa_id = pmsa.idsession.commit()return Truedef add_sales_associate(pmsa, referrerEmail, l1_userEmail):d_pmsa = PMSA.query.filter(or_(PMSA.emailId == pmsa.emailId, PMSA.phone == pmsa.phone)).all()if d_pmsa:return "User with same phone or email already exists"referrer = PMSA.get_by(emailId = referrerEmail, activated=True)d_pmsa = PMSA()d_pmsa.name = pmsa.named_pmsa.phone = pmsa.phoned_pmsa.emailId = pmsa.emailIdd_pmsa.address = pmsa.addressd_pmsa.state = pmsa.stated_pmsa.level = pmsa.leveld_pmsa.activated = pmsa.activatedd_pmsa.pin = pmsa.pinif referrerEmail != l1_userEmail:if referrer is None or referrer.level != 'L2':return "Not valid referrer"l1_user = PMSA.get_by(id = referrer.l1_id)if l1_user.emailId != l1_userEmail:return "You are not authorized to refer"d_pmsa.l2_id = referrer.idelse:l1_user = referrerd_pmsa.l1_id = l1_user.idfor i in range(0,5):activation_code = "SA"+str(generate_random_code(8))code_exists = PMSA.get_by(code=activation_code)if not code_exists:breakif i==4:return "Activation code generation failed"d_pmsa.code = activation_codesession.commit()return "User added successfully.Activation Code %s"%(activation_code)def search_pmsa(pmsaSearchFilter, associateEmail):associate = PMSA.get_by(emailId = associateEmail)query = session.query(PMSA).filter(PMSA.l1_id == associate.id)if pmsaSearchFilter.name:query = query.filter(PMSA.name == pmsaSearchFilter.name)if pmsaSearchFilter.emailId:query = query.filter(PMSA.emailId == pmsaSearchFilter.emailId)if pmsaSearchFilter.phone:query = query.filter(PMSA.phone == pmsaSearchFilter.phone)if pmsaSearchFilter.code:query = query.filter(PMSA.code == pmsaSearchFilter.code)if pmsaSearchFilter.l2_email:referrer = PMSA.get_by(emailId = pmsaSearchFilter.l2_email)if referrer:query = query.filter(PMSA.l2_id == referrer.id)else:return []return query.all()def get_pmsa_user(id, associateEmail):associate = PMSA.get_by(emailId = associateEmail)if id is None:return associatepmsa = PMSA.get_by(id=id)if pmsa.l1_id != associate.id:return Nonel2_user_email = ""if pmsa.l2_id:l2_user = PMSA.get_by(id=pmsa.l2_id)l2_user_email = l2_user.emailIdreturn pmsa, associate.emailId, l2_user_emaildef update_pmsa_user(pmsa, associateEmail):d_pmsa = PMSA.query.filter(or_(PMSA.emailId == pmsa.emailId, PMSA.phone == pmsa.phone)).all()if not d_pmsa or (len(d_pmsa)==1 and d_pmsa[0].id == pmsa.id):n_pmsa = PMSA.get_by(id=pmsa.id)associate = PMSA.get_by(emailId = associateEmail)if n_pmsa.l1_id != associate.id:return "You dont have permission to edit this user"n_pmsa.name = pmsa.namen_pmsa.phone = pmsa.phonen_pmsa.emailId = pmsa.emailIdn_pmsa.address = pmsa.addressn_pmsa.state = pmsa.staten_pmsa.activated = pmsa.activatedn_pmsa.pin = pmsa.pinsession.commit()return "User updated successfully"return "User with same email or phone exists"def get_pending_pmsa(associateEmail):associate = PMSA.get_by(emailId = associateEmail)query = session.query(PMSA).filter(PMSA.l1_id == associate.id).filter(PMSA.activated == False)return query.all()def get_pmsa_users(associateEmail):associate = PMSA.get_by(emailId = associateEmail)query = session.query(PMSA).filter(PMSA.l1_id == associate.id).order_by(desc(PMSA.createdAt))return query.all()def get_stats_for_associates(associateEmail):a = PMSA.get_by(emailId = associateEmail)if a is None:return [0,0,0,0,0]l2 = session.query(PMSA.id).filter(PMSA.l1_id == a.id).filter(PMSA.level == "L2").count()l3 = session.query(PMSA.id).filter(PMSA.l1_id == a.id).filter(PMSA.level == "L3").count()not_activated = session.query(PMSA.id).filter(PMSA.l1_id == a.id).filter(PMSA.activated == False).count()total = session.query(PMSA.id).filter(PMSA.l1_id == a.id).count()return [l2,l3,total,not_activated,total-not_activated]def credit_user_wallet(userId, amount, cash_back, shortDesc):user_client = UserClient().get_client()t_user = user_client.getUserById(userId)if t_user.userId == -1:raiseif amount <0 :reference = [int(s) for s in shortDesc.split() if s.isdigit()][0]consume_wallet(userId, -amount, reference, WalletReferenceType.ADVANCE_REVERSAL, shortDesc)return Trueap = AdvancePayments()ap.userId = userIdap.amount = amountap.cash_back = cash_backap.cash_back_type = "PERCENTAGE"ap.cash_back_amount = int(math.floor(amount * (cash_back/100)))session.commit()if not shortDesc:shortDesc = "Paid in advance"add_amount_in_wallet(userId, ap.amount + ap.cash_back_amount, ap.id, WalletReferenceType.ADVANCE_AMOUNT, True, shortDesc, commit_session=True)return True#refund complete shipping if type is list else as per mapdef __refund_shipping(orders, commit=True):if type(orders) is list:for order in orders:if order.shippingRefund < order.shippingCost:diff = order.shippingCost - order.shippingRefundorder.shippingRefund = order.shippingCostadd_amount_in_wallet(order.customer_id, diff, order.transaction_id, WalletReferenceType.SHIPPING_REFUND, False, "Refunded shipping charges", commit_session=False)if commit:session.commit()#def mark_order_for_selfpickup(transaction_ids):# for transaction_id in transaction_ids:# transaction = get_transaction(transaction_id)# user_client = UserClient().get_client()# counter = user_client.getCounterByUserId(transaction.customer_id)# address = user_client.getAddressById(counter.address)# for order in transaction.orders:# oa = Attribute()# oa.value = counter.tin# oa.name='tinNumber'# oa.orderId = order.id## order.customer_name = address.name# order.customer_pincode = address.pin# order.customer_address1 = address.line1# order.customer_address2 = address.line2# order.customer_city = address.city# order.customer_state = address.state# order.orderType = OrderType.B2B# #Self Pickup# order.logistics_provider_id = 4# __refund_shipping(list(transaction.orders), False)# session.commit()# session.close()##This should be called before order processing#Billing address is set using this for invoicing purposesdef mark_order_for_registered_gst_invoice(transaction_ids):try:for transaction_id in transaction_ids:transaction = get_transaction(transaction_id)user_client = UserClient().get_client()counter = user_client.getCounterByUserId(transaction.customer_id)address = user_client.getAddressById(counter.address)for order in transaction.orders:order.customer_name = address.nameorder.customer_pincode = address.pinorder.customer_address1 = address.line1order.customer_address2 = address.line2order.customer_city = address.cityorder.customer_state = address.stateorder.orderType = OrderType.B2Bsession.commit()return Trueexcept:logging.info("Tried accessing counter for user id {0} - {1}".format(transaction.customer_id, transaction.orders[0].customer_email))return Falsefinally:session.close()def get_in_transit_orders():try:warehouseDbConnection = getDbConnection("192.168.190.114","root", "shop2020", "warehouse")except:raise TransactionServiceException(302, "Unable to connect to Warehouse System")whCursor = warehouseDbConnection.cursor()def is_shipment_cod(logisticsTransactionId):orders = Order.query.filter_by(logisticsTransactionId=logisticsTransactionId).all()net_payable = 0for order in orders:if order.cod == 0:return Falseelse:net_payable += order.net_payable_amountreturn True if net_payable > 0 else Falsedef get_intransit_orders_on_date_by_item_id(closingDate, itemId):closingDateInclusive = to_py_date(closingDate) + datetime.timedelta(days=1)orders = Order.query.options(joinedload('lineitems')).filter(Order.lineitems.any(item_id=itemId)).filter(Order.billing_timestamp < closingDateInclusive).filter(or_(Order.refund_timestamp >= closingDateInclusive, Order.delivery_timestamp >= closingDateInclusive)).all()print len(orders)t_orders = []for order in orders:if order.lineitems[0].item_id==itemId:t_orders.append(to_t_order(order))return t_ordersdef get_intransit_orders_on_date(closingDate):closingDateInclusive = to_py_date(closingDate) + datetime.timedelta(days=1)orders = Order.query.options(joinedload('lineitems')).filter(Order.billing_timestamp < closingDateInclusive).filter(or_(Order.refund_timestamp >= closingDateInclusive, Order.delivery_timestamp >= closingDateInclusive)).all()return [to_t_order(order) for order in orders]def add_price_drop(item_id, imeis, amount, affected_on):priceDrop = Price_Drop()priceDrop.amount = amountpriceDrop.affected_on = to_py_date(affected_on)priceDrop.created_on = datetime.datetime.now()priceDrop.item_id = item_idfor imei in imeis:pdImei = Price_Drop_IMEI()pdImei.imei = imeipdImei.price_drop = priceDropsession.commit()return Truedef process_failed_payment(new_status, transaction_id, description, sourceId, pickUp):logging.info("########change transaction status called" + str(transaction_id))transaction = get_transaction(transaction_id)transaction.status = new_statustransaction.status_message = descriptionorder = transaction.orders[0]expectedDelayMap = {}billingWarehouseIdMap = {}billingWarehouseTxnMap = {}if new_status == TransactionStatus.FAILED:for order in transaction.orders:order.status = OrderStatus.PAYMENT_FAILEDorder.statusDescription = "Payment Failed"elif new_status == TransactionStatus.AUTHORIZED or new_status == TransactionStatus.FLAGGED:user_client = UserClient().get_client()catalog_client = CatalogClient().get_client()pdu = user_client.getPrivateDealUser(transaction.orders[0].customer_id)print "pdu.isFofo----", pdu.isFofofofoWarehousesMap = {}if pdu.isFofo:fofoDealMap = catalog_client.getAllFofoDeals([order.lineitems[0].item_id], [4,7])if fofoDealMap:itemIds = []for order in transaction.orders:itemIds.append(order.lineitems[0].item_id)inventory_client = InventoryClient().get_client()print "calling getFofoFulFillmentWarehouseMap"fofoWarehousesMap = inventory_client.getFofoFulFillmentWarehouseMap(itemIds)print "called getFofoFulFillmentWarehouseMap"expectedDelayMap = {}billingWarehouseIdMap = {}billingWarehouseTxnMap = {}subOrderAmountsMap = {}for order in transaction.orders:if new_status == TransactionStatus.AUTHORIZED:order.status = OrderStatus.SUBMITTED_FOR_PROCESSINGorder.statusDescription = "Submitted to warehouse"elif new_status == TransactionStatus.FLAGGED:order.status = OrderStatus.PAYMENT_FLAGGEDorder.statusDescription = "Payment flagged by gateway"order.cod = False#Order type cant be changed during authorization#if orderType is not None:# order.orderType = orderType#After we got payment success, we will set logistics info alsologistics_client = LogisticsClient().get_client()#FIXME line item is only one now. If multiple will come, need to fix.item_id = order.lineitems[0].item_idif pickUp == PickUpType.RUNNER or pickUp == PickUpType.SELF:current_time = datetime.datetime.now()if pdu.isFofo:stateMaster = fetchStateMaster()stateId = -1for k, v in stateMaster.iteritems():if v.stateName == order.customer_state:stateId = kbreaklogistics_info = logistics_client.getLogisticsInfo(order.customer_pincode, item_id, DeliveryType.PREPAID, pickUp, stateId)else:logistics_info = logistics_client.getLogisticsInfo(order.customer_pincode, item_id, DeliveryType.PREPAID, pickUp, -1)order.logistics_provider_id = logistics_info.providerIdorder.warehouse_id = logistics_info.warehouseIdorder.fulfilmentWarehouseId = logistics_info.fulfilmentWarehouseIdlogistics_info.deliveryTime = adjust_delivery_time(current_time, logistics_info.deliveryTime)logistics_info.shippingTime = adjust_delivery_time(current_time, logistics_info.shippingTime)logistics_info.deliveryDelay = adjust_delivery_time(current_time, (logistics_info.shippingTime+logistics_info.deliveryDelay))order.courier_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryDelay)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)order.expected_shipping_time = (current_time + datetime.timedelta(days=logistics_info.shippingTime)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)order.promised_shipping_time = order.expected_shipping_timeorder.expected_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryTime)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)order.promised_delivery_time = order.expected_delivery_timeorder.otg = Falseinventory_client = InventoryClient().get_client()if order.productCondition != ProductCondition.BAD:inventory_client.reserveItemInWarehouse(item_id, order.fulfilmentWarehouseId, sourceId, order.id, to_java_date(order.created_timestamp), to_java_date(order.promised_shipping_time), order.lineitems[0].quantity)elif order.source == OrderSource.WEBSITE:try:#Get the id and location of actual warehouse that'll be used to fulfil this order.inventory_client = InventoryClient().get_client()fulfilmentWhId, expected_delay, billingWarehouseId, sellingPrice, totalAvailability, weight = inventory_client.getItemAvailabilityAtLocation(item_id, 1, -1)except Exception as ex:raise TransactionServiceException(103, "Unable to fetch inventory information about this item.")expectedDelayMap[item_id] = expected_delayif billingWarehouseIdMap.has_key(billingWarehouseId):ordersList = billingWarehouseIdMap.get(billingWarehouseId)ordersList.append(order)billingWarehouseIdMap[billingWarehouseId] = ordersListelse:ordersList = []ordersList.append(order)billingWarehouseIdMap[billingWarehouseId] = ordersListif billingWarehouseTxnMap.has_key(billingWarehouseId):transactionAmount , transactionWeight = billingWarehouseTxnMap.get(billingWarehouseId)transactionAmount = transactionAmount+order.total_amounttransactionWeight = transactionWeight+order.total_weightbillingWarehouseTxnMap[billingWarehouseId] = transactionAmount , transactionWeightelse:billingWarehouseTxnMap[billingWarehouseId] = order.total_amount , order.total_weightsubOrderAmountsMap[long(order.lineitems[0].unit_price)] = orderorder.fulfilmentWarehouseId = fulfilmentWhIdorder.warehouse_id = billingWarehouseIdif order.productCondition != ProductCondition.BAD:inventory_client.reserveItemInWarehouse(item_id, order.fulfilmentWarehouseId, sourceId, order.id, to_java_date(order.created_timestamp), to_java_date(order.promised_shipping_time), order.lineitems[0].quantity)try:item_pricing = inventory_client.getItemPricing(item_id, -1)order.lineitems[0].transfer_price = item_pricing.transferPriceorder.lineitems[0].nlc = item_pricing.nlcexcept:print "Not able to get transfer price. Skipping"elif new_status == TransactionStatus.COD_IN_PROCESS:expectedDelayMap = {}billingWarehouseIdMap = {}billingWarehouseTxnMap = {}subOrderAmountsMap = {}for order in transaction.orders:order.status = OrderStatus.COD_VERIFICATION_PENDINGorder.statusDescription = "Verification Pending"order.cod = True#OrderType cant be changed#order.orderType = orderType#After we got payment success, we will set logistics info alsologistics_client = LogisticsClient().get_client()#FIXME line item is only one now. If multiple will come, need to fix.item_id = order.lineitems[0].item_idtry:#Get the id and location of actual warehouse that'll be used to fulfil this order.inventory_client = InventoryClient().get_client()fulfilmentWhId, expected_delay, billingWarehouseId, sellingPrice, totalAvailability, weight = inventory_client.getItemAvailabilityAtLocation(item_id, 1, -1)except Exception as ex:raise TransactionServiceException(103, "Unable to fetch inventory information about this item.")expectedDelayMap[item_id] = expected_delayif billingWarehouseIdMap.has_key(billingWarehouseId):ordersList = billingWarehouseIdMap.get(billingWarehouseId)ordersList.append(order)billingWarehouseIdMap[billingWarehouseId] = ordersListelse:ordersList = []ordersList.append(order)billingWarehouseIdMap[billingWarehouseId] = ordersListif billingWarehouseTxnMap.has_key(billingWarehouseId):transactionAmount , transactionWeight = billingWarehouseTxnMap.get(billingWarehouseId)transactionAmount = transactionAmount+order.total_amounttransactionWeight = transactionWeight+order.total_weightbillingWarehouseTxnMap[billingWarehouseId] = transactionAmount , transactionWeightelse:billingWarehouseTxnMap[billingWarehouseId] = order.total_amount , order.total_weightsubOrderAmountsMap[long(order.lineitems[0].unit_price)] = orderorder.fulfilmentWarehouseId = fulfilmentWhIdorder.warehouse_id = billingWarehouseIdif order.productCondition != ProductCondition.BAD:inventory_client.reserveItemInWarehouse(item_id, order.fulfilmentWarehouseId, sourceId, order.id, to_java_date(order.created_timestamp), to_java_date(order.promised_shipping_time), order.lineitems[0].quantity)try:item_pricing = inventory_client.getItemPricing(item_id, -1)order.lineitems[0].transfer_price = item_pricing.transferPriceorder.lineitems[0].nlc = item_pricing.nlcexcept:print "Not able to get transfer price. Skipping"session.commit()if new_status in (TransactionStatus.AUTHORIZED, TransactionStatus.FLAGGED, TransactionStatus.COD_IN_PROCESS):try:if order.source == OrderSource.WEBSITE:if new_status == TransactionStatus.COD_IN_PROCESS:transaction_requiring_extra_processing = TransactionRequiringExtraProcessing()transaction_requiring_extra_processing.category = 'COD_VERIFICATION'transaction_requiring_extra_processing.transaction_id = transaction_idsession.commit()elif new_status == TransactionStatus.FLAGGED:transaction_requiring_extra_processing = TransactionRequiringExtraProcessing()transaction_requiring_extra_processing.category = 'PAYMENT_FLAGGED'transaction_requiring_extra_processing.transaction_id = transaction_idsession.commit()else:order.otg = Falsesession.commit()except Exception as e:print "Error inserting transaction Id: " + str(transaction_id) + " due to " + str(e)return Trueif __name__ == '__main__':DataService.initialize(db_hostname="192.168.190.112")#transaction_ids=[1030084,1030087,1030090,1030093,1030096,1030099,1030102,1030105,1030108,1030111,1030114,1030117,1030120,1030123,1030144,1030147,1030153]#transaction_ids=[1043579, 1043580, 1043581, 1043582, 1043584, 1043588, 1043589]#transaction_ids=[1043577]#for transaction_id in transaction_ids:# process_failed_payment(TransactionStatus.AUTHORIZED, transaction_id, "Transaction Authorised", 1, PickUpType.SELF)###################################################################################################################################refund_order(1588409, "backend-team", "As per Customer's Request")# mark_order_for_selfpickup_temp(transaction_ids)# get_billed_orders_for_manifest_gen(7441, 2, True)# ordersmap = {'911319502886601':1544266,'911319502890314':1544266,'x911319502903141':1544269,'x911319502916655':1544269,'x911319502950985':1544269,'x911319502836309':1544269,'x911319502972369':1544269,'x911319502950860':1544269,'x911319502918313':1544269,# 'x911319502943436':1544269,'x911319502928056':1544269,'x911319502838263':1544269,'911319502794144':1544269,'x911319502821616':1544269,'x911319502974746':1544269,'x911319502821442':1544269,'x911319502903984':1544269,'x911319502820980':1544269,# 'x911319502973102':1544269,'x911319502913009':1544269,'x911319502973979':1544269,'x911319502842729':1544269,'x911319502824784':1544269,'x911319502847249':1544269,'x911319502848387':1544269,'x911319502887021':1544269,'x911319502962634':1544269,# 'x911319502826268':1544269,'x911319502785761':1544269,'x911319502956750':1544269,'x911319502825195':1544269,'x911319502828298':1544269,'x911319502972054':1544269,'x911319502902044':1544269,'x911319502846498':1544269,'x911319502824305':1544269,# 'x911319502891478':1544269,'x911319502962451':1544269,'x911319502929732':1544269,'x911319502834304':1544269,'x911319502830575':1544269,'x911319502889456':1544269,'x911319502842521':1544269,'x911319502900998':1544269,'x911319502890462':1544269,'x911319502881222':1544269,'x911319503523252':1544269}## invoice_number=''# itemNumbersMap={}# serialNumbersMap={}# from shop2020.model.v1.order.impl import DataService# from shop2020.model.v1.order.impl.DataAccessors import add_billing_details_for_groupped_orders# DataService.initialize('transaction','192.168.190.114')# for k,v in ordersmap.iteritems():# if not serialNumbersMap.has_key(v):# serialNumbersMap[v]=[]# arr = serialNumbersMap.get(v)# arr.append(k)# order_ids=serialNumbersMap.keys()# for order_id in order_ids:# itemNumbersMap[order_id]=['1']# add_billing_details_for_groupped_orders(order_ids, invoice_number, itemNumbersMap, serialNumbersMap, {}, 'mp-mmx-admin', '1', 0, False, 'Individual')#from shop2020.clients.LogisticsClient import LogisticsClient#pincodes = [302006,263139,781001,834001,380051,380001,110074,400095,560037,125055,122001,700009,400709,462022,700023,400015]#logistics_client = LogisticsClient().get_client()#for pincode in pincodes:# print pincode, logistics_client.getLogisticsEstimation(26385, str(pincode), 1).providerId#add_price_drop(213, ['1','2'], 20, 1513686198574)