Subversion Repositories SmartDukaan

Rev

Rev 7386 | Rev 7392 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
6903 anupam.sin 1
# -*- coding: utf-8 -*-
2
 
104 ashish 3
'''
4
Created on 29-Mar-2010
5
 
2536 chandransh 6
@author: Chandranshu
104 ashish 7
'''
2536 chandransh 8
 
4369 rajveer 9
from datetime import date, timedelta
7151 amit.gupta 10
from decimal import Decimal
11
from elixir import *
6424 rajveer 12
from math import ceil
5944 mandeep.dh 13
from random import randrange
7151 amit.gupta 14
from reportlab.lib.enums import TA_CENTER, TA_JUSTIFY
15
from reportlab.lib.styles import ParagraphStyle, getSampleStyleSheet
3499 mandeep.dh 16
from reportlab.lib.units import inch
2536 chandransh 17
from reportlab.pdfgen.canvas import Canvas
6980 anupam.sin 18
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Image, \
19
    BaseDocTemplate, Frame, PageTemplate
7151 amit.gupta 20
from reportlab.rl_config import defaultPageSize
5944 mandeep.dh 21
from shop2020.clients.AlertClient import AlertClient
3499 mandeep.dh 22
from shop2020.clients.CatalogClient import CatalogClient
23
from shop2020.clients.HelperClient import HelperClient
5944 mandeep.dh 24
from shop2020.clients.InventoryClient import InventoryClient
3499 mandeep.dh 25
from shop2020.clients.LogisticsClient import LogisticsClient
2747 chandransh 26
from shop2020.clients.PaymentClient import PaymentClient
7151 amit.gupta 27
from shop2020.clients.PromotionClient import PromotionClient
3499 mandeep.dh 28
from shop2020.clients.UserClient import UserClient
29
from shop2020.clients.WarehouseClient import WarehouseClient
7151 amit.gupta 30
from shop2020.config.client.ConfigClient import ConfigClient
3499 mandeep.dh 31
from shop2020.model.v1 import order
6048 rajveer 32
from shop2020.model.v1.order.impl import DataService, RechargeService
7198 amar.kumar 33
from shop2020.model.v1.order.impl.Convertors import to_t_emi_scheme, to_t_order
3499 mandeep.dh 34
from shop2020.model.v1.order.impl.DataService import Transaction, LineItem, \
4435 mandeep.dh 35
    Order, BatchNoGenerator, InvoiceIDGenerator, TransactionRequiringExtraProcessing, \
5348 anupam.sin 36
    OrderInventory, Alert, PaymentSettlement, EBSSettlementSummary, \
7151 amit.gupta 37
    CodVerificationAgent, Attribute, RechargeVoucherTracker, EmiScheme, MiscCharges, \
38
    BlockedIpRange, DeniedIpAddress, InsuranceDetailForOrder, DocumentStore, \
39
    RechargeTransaction, HotspotStore, WalletForCompany, WalletHistoryForCompany, \
7311 kshitij.so 40
    FRC, OperatorSeries, SourceDetail, Company, \
7386 anupam.sin 41
    AmazonOrder, StoreOrderDetail, EdcBank
7151 amit.gupta 42
from shop2020.model.v1.order.impl.model.BaseOrder import BaseOrder
43
from shop2020.model.v1.order.impl.model.DTHRechargeOrder import DTHRechargeOrder
6000 mandeep.dh 44
from shop2020.model.v1.order.impl.model.MobileRechargeOrder import \
45
    MobileRechargeOrder
7151 amit.gupta 46
from shop2020.model.v1.order.impl.model.RechargeDenomination import \
47
    RechargeDenomination
48
from shop2020.model.v1.order.impl.model.RechargeOrder import RechargeOrder
49
from shop2020.model.v1.order.impl.model.RechargePlan import RechargePlan
2687 chandransh 50
from shop2020.model.v1.order.impl.model.ReturnOrder import ReturnOrder
7151 amit.gupta 51
from shop2020.model.v1.order.impl.model.ServiceAvailability import \
52
    ServiceAvailability
53
from shop2020.model.v1.order.impl.model.ServiceProvider import ServiceProvider
54
from shop2020.model.v1.order.impl.model.TelecomCircle import TelecomCircle
55
from shop2020.model.v1.order.impl.model.UserWallet import UserWallet
56
from shop2020.model.v1.order.impl.model.UserWalletHistory import \
57
    UserWalletHistory
5944 mandeep.dh 58
from shop2020.thriftpy.alert.ttypes import MonitoredEntity, EntityType
5527 anupam.sin 59
from shop2020.thriftpy.logistics.ttypes import DeliveryType, PickUpType
6000 mandeep.dh 60
from shop2020.thriftpy.model.v1.catalog.ttypes import ItemType
5944 mandeep.dh 61
from shop2020.thriftpy.model.v1.inventory.ttypes import BillingType, \
62
    InventoryServiceException, WarehouseType, InventoryType
4435 mandeep.dh 63
from shop2020.thriftpy.model.v1.order.ttypes import TransactionServiceException, \
64
    TransactionStatus, OrderStatus, DelayReason, ExtraTransactionProcessingType, \
7151 amit.gupta 65
    HotspotAction, TimeoutSummary, OrderStatusGroups, OrderType, RechargeOrderStatus, \
7293 anupam.sin 66
    RechargeType, RechargeStatistics, DeviceNumberInfo, EmiChargeType, PayMethod, OrderSource
5944 mandeep.dh 67
from shop2020.thriftpy.model.v1.user.ttypes import VoucherType
4421 mandeep.dh 68
from shop2020.thriftpy.payments.ttypes import PaymentException
5110 mandeep.dh 69
from shop2020.thriftpy.warehouse.ttypes import ScanType, \
70
    WarehouseServiceException
6000 mandeep.dh 71
from shop2020.utils.EmailAttachmentSender import mail, get_attachment_part
855 rajveer 72
from shop2020.utils.Utils import to_py_date, to_java_date
4008 mandeep.dh 73
from sqlalchemy.orm.exc import NoResultFound, MultipleResultsFound
3499 mandeep.dh 74
from sqlalchemy.sql import func
7151 amit.gupta 75
from sqlalchemy.sql.expression import and_, or_, desc, not_, distinct, cast, \
76
    between
3499 mandeep.dh 77
from string import Template
78
from textwrap import dedent
79
import datetime
5944 mandeep.dh 80
import httplib
3499 mandeep.dh 81
import logging
82
import os
4421 mandeep.dh 83
import sys
4435 mandeep.dh 84
import time
4421 mandeep.dh 85
import traceback
5806 rajveer 86
import urllib
7308 rajveer 87
import base64
6307 anupam.sin 88
 
5944 mandeep.dh 89
 
3499 mandeep.dh 90
logging.basicConfig(level=logging.DEBUG)
104 ashish 91
 
5966 rajveer 92
sourceId = int(ConfigClient().get_property("sourceid"))
93
mail_user = 'cnc.center@shop2020.in'
94
mail_password = '5h0p2o2o'
95
help_user = 'help@shop2020.in'
96
help_password = '5h0p2o2o'
6029 rajveer 97
source_url = 'www.saholic.com'
98
source_name = 'Saholic'
3499 mandeep.dh 99
 
4763 rajveer 100
PREPAID_SHIPPING_CUTOFF_TIME = 15
4019 chandransh 101
COD_SHIPPING_CUTOFF_TIME = 12
3499 mandeep.dh 102
 
2819 chandransh 103
PAGE_HEIGHT=defaultPageSize[1]
104
PAGE_WIDTH=defaultPageSize[0]
105
 
4763 rajveer 106
billedOrdersColorMap = {}
107
 
3499 mandeep.dh 108
ORDER_STATUS_TO_USER_TRUST_LEVEL_DELTA_DICT = {
4873 mandeep.dh 109
        OrderStatus.RTO_RESHIPPED    :  3,
110
        OrderStatus.RTO_IN_TRANSIT   : -5,
111
        OrderStatus.DELIVERY_SUCCESS :  1,
112
        OrderStatus.DOA_CERT_INVALID : -5
3499 mandeep.dh 113
}
114
 
5783 rajveer 115
delhi_pincodes = ['110001','110002','110003','110004','110005','110006','110007','110008','110009','110010','110011','110012','110013','110014','110015',\
116
                '110016','110017','110018','110019','110020','110021','110022','110023','110024','110025','110026','110027','110028','110029','110030',\
117
                '110031','110032','110033','110034','110035','110037','110038','110041','110042','110044','110045','110046','110047','110048','110049',\
118
                '110051','110052','110053','110054','110055','110056','110057','110058','110059','110060','110061','110062','110063','110064','110065',\
119
                '110066','110067','110068','110070','110071','110074','110075','110076','110078','110081','110082','110083','110084','110085','110086',\
120
                '110087','110088','110089','110091','110092','110093','110094','110095','110096','110101','110103','110104','110105','110106','110107',\
121
                '110108','110109','110110','110112','110113','110114','110115','110116','110117','110118','110119','110120','110122','110124','110125',\
122
                '110301','110302','110501','110502','110503','110504','110505','110510','110511','110512','110601','110602','110603','110604','110605',\
123
                '110606','110607','110608','110609']
124
 
104 ashish 125
def get_new_transaction():
126
    transaction = Transaction()
127
    transaction.createdOn = datetime.datetime.now()
738 chandransh 128
    transaction.status = TransactionStatus.INIT
104 ashish 129
    transaction.status_message = "New transaction"
483 rajveer 130
    return transaction
131
 
132
def create_order(t_order):
133
    order = Order()
134
    if t_order.warehouse_id:
135
        order.warehouse_id = t_order.warehouse_id
509 rajveer 136
    if t_order.logistics_provider_id:    
483 rajveer 137
        order.logistics_provider_id = t_order.logistics_provider_id
138
        order.airwaybill_no = t_order.airwaybill_no
139
        order.tracking_id = t_order.tracking_id
4009 chandransh 140
    if t_order.expected_shipping_time:
4019 chandransh 141
        order.expected_shipping_time = to_py_date(t_order.expected_shipping_time).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
4102 chandransh 142
        order.promised_shipping_time = order.expected_shipping_time
4009 chandransh 143
    if t_order.expected_delivery_time:
483 rajveer 144
        order.expected_delivery_time = to_py_date(t_order.expected_delivery_time)
4102 chandransh 145
        order.promised_delivery_time = order.expected_delivery_time
483 rajveer 146
    if t_order.customer_id:    
147
        order.customer_id = t_order.customer_id
148
        order.customer_name = t_order.customer_name
860 rajveer 149
        order.customer_city = t_order.customer_city
150
        order.customer_state = t_order.customer_state
483 rajveer 151
        order.customer_mobilenumber = t_order.customer_mobilenumber
152
        order.customer_pincode = t_order.customer_pincode
738 chandransh 153
        order.customer_address1 = t_order.customer_address1
154
        order.customer_address2 = t_order.customer_address2
483 rajveer 155
        order.customer_email = t_order.customer_email
156
    #new status and status description to be added    
716 rajveer 157
    order.status = t_order.status  
483 rajveer 158
    order.statusDescription = t_order.statusDescription
159
    order.total_amount = t_order.total_amount
6318 rajveer 160
    order.gvAmount = t_order.gvAmount
483 rajveer 161
    order.total_weight = t_order.total_weight
162
    if t_order.created_timestamp:
163
        order.created_timestamp = to_py_date(t_order.created_timestamp)
164
    else:
685 chandransh 165
        order.created_timestamp = datetime.datetime.now()
5555 rajveer 166
    order.pickupStoreId = t_order.pickupStoreId
7033 anupam.sin 167
    if t_order.insurer:
168
        order.insurer = t_order.insurer
169
        order.insuranceAmount = t_order.insuranceAmount
6903 anupam.sin 170
    if order.insurer > 0:
171
        insuranceDetail = InsuranceDetailForOrder()
172
        insuranceDetail.dob = t_order.dob
173
        insuranceDetail.guardianName = t_order.guardianName
174
        insuranceDetail.order = order
7190 amar.kumar 175
    if t_order.freebieItemId:
176
        order.freebieItemId = t_order.freebieItemId
7293 anupam.sin 177
    order.source = t_order.source
178
    order.advanceAmount = t_order.advanceAmount
179
    order.storeId = t_order.storeId
483 rajveer 180
    return order
181
 
182
def create_transaction(t_transaction):
183
    t_orders = t_transaction.orders
184
    if not t_orders:
185
        raise TransactionServiceException(101, "Orders missing from the transaction")
186
    transaction = get_new_transaction()
187
    transaction.customer_id = t_transaction.customer_id 
188
    transaction.shopping_cart_id = t_transaction.shoppingCartid
2219 varun.gupt 189
    transaction.coupon_code = t_transaction.coupon_code
2815 vikas 190
    transaction.session_source = t_transaction.sessionSource
191
    transaction.session_start_time = to_py_date(t_transaction.sessionStartTime)
3858 vikas 192
    transaction.first_source = t_transaction.firstSource
193
    transaction.first_source_start_time = to_py_date(t_transaction.firstSourceTime)
483 rajveer 194
 
6389 rajveer 195
    totalAmount = 0
483 rajveer 196
    for t_order in t_orders:
197
        order = create_order(t_order)
6389 rajveer 198
        totalAmount = totalAmount + order.total_amount
483 rajveer 199
        order.transaction = transaction 
200
        for line_item in t_order.lineitems:
201
            litem = LineItem()
716 rajveer 202
            litem.item_id = line_item.item_id
963 chandransh 203
            litem.productGroup = line_item.productGroup
483 rajveer 204
            litem.brand = line_item.brand
205
            if line_item.model_number:
206
                litem.model_number = line_item.model_number
207
            if line_item.model_name:    
208
                litem.model_name = line_item.model_name
908 chandransh 209
            if line_item.color:
210
                litem.color = line_item.color
483 rajveer 211
            if line_item.extra_info:
212
                litem.extra_info = line_item.extra_info
213
            litem.quantity = line_item.quantity
214
            litem.unit_price = line_item.unit_price
215
            litem.unit_weight = line_item.unit_weight
216
            litem.total_price = line_item.total_price
217
            litem.total_weight = line_item.total_weight
4283 anupam.sin 218
            '''litem.transfer_price = line_item.transfer_price'''
4172 rajveer 219
            litem.dealText = line_item.dealText
4295 varun.gupt 220
            litem.warranty_expiry_timestamp = to_py_date(line_item.warrantry_expiry_timestamp)
1976 varun.gupt 221
 
483 rajveer 222
            """
223
            if line_item.addedOn:
224
                litem.added_on = to_py_date(line_item.addedOn)
225
            else:
226
                litem.added_on = datetime.datetime.now()
227
            """
228
            litem.order = order
229
    session.commit()
6389 rajveer 230
 
231
    generateOtherCharges(transaction, t_transaction.emiSchemeId, totalAmount)
232
 
483 rajveer 233
    return transaction.id
234
 
6389 rajveer 235
def generateOtherCharges(transaction, emiSchemeId, totalAmount):
236
    emiScheme = EmiScheme.get_by(id=emiSchemeId)
237
    if not emiScheme:
238
        return
239
 
240
    if totalAmount < emiScheme.minAmount:
241
        return
242
 
243
    emiCharge = 0
244
    if emiScheme.chargeType == EmiChargeType.FIXED:
6424 rajveer 245
        emiCharge = ceil(emiScheme.chargeValue)
6389 rajveer 246
    if emiScheme.chargeType == EmiChargeType.PERCENTAGE:
6424 rajveer 247
        emiCharge = ceil(totalAmount*(emiScheme.chargeValue)/100)
6736 amit.gupta 248
 
249
    if transaction.coupon_code is not None and transaction.coupon_code != "":    
250
        try:
251
            promotion_client = PromotionClient().get_client()
252
            emis = promotion_client.getEmiDiscount(transaction.shopping_cart_id)
253
            if emis.has_key(emiSchemeId):
254
                discount = emis.get(emiSchemeId)
255
                if emiCharge > discount:
256
                    emiCharge -= discount
257
                else:
258
                    emiCharge = 0
259
        except:
260
            print "Could not get emi discounts from promotion"
261
 
6389 rajveer 262
    miscCharge = MiscCharges()
263
    miscCharge.transaction = transaction
264
    miscCharge.chargeType = 1 ##EMI charges
265
    miscCharge.chargeAmount = emiCharge
266
    session.commit()
267
 
483 rajveer 268
def get_transaction(transaction_id):
269
    transaction = Transaction.get_by(id=transaction_id)
270
    if not transaction:
271
        raise TransactionServiceException(108, "no such transaction")
272
 
273
    return transaction
274
 
275
def get_transactions_for_customer(customer_id, from_date, to_date, status):
276
    if not customer_id:
277
        raise TransactionServiceException(101, "bad customer id")
278
    query = Transaction.query.filter(Transaction.customer_id == customer_id)
1493 vikas 279
    if status is not None:
483 rajveer 280
        query = query.filter(Transaction.status == status)
281
    if from_date:
282
        query = query.filter(Transaction.createdOn >from_date)
283
    if to_date:
284
        query = query.filter(Transaction.createdOn < to_date)
285
    return query.all()
286
 
287
def get_transactions_for_shopping_cart_id(shopping_cart_id):
288
    transactions = Transaction.query.filter_by(shopping_cart_id=shopping_cart_id).all()
289
    return transactions
290
 
291
def get_transaction_status(transaction_id):
292
    if not transaction_id:
293
        raise TransactionServiceException(101, "bad transaction id")
294
 
295
    transaction = get_transaction(transaction_id)
296
 
297
    return transaction.status
298
 
7293 anupam.sin 299
def change_transaction_status(transaction_id, new_status, description, pickUp, orderType, source):
483 rajveer 300
    transaction = get_transaction(transaction_id)
301
    transaction.status = new_status
302
    transaction.status_message = description
5783 rajveer 303
    ## Assign runner in case of delhi pincodes
5784 rajveer 304
    if transaction.orders[0].pickupStoreId:
305
        logistics_client = LogisticsClient().get_client() 
306
        store = logistics_client.getPickupStore(transaction.orders[0].pickupStoreId)
307
        if delhi_pincodes.__contains__(store.pin):
5793 rajveer 308
            pickUp = PickUpType.RUNNER  
5783 rajveer 309
 
690 chandransh 310
    if new_status == TransactionStatus.FAILED:
311
        for order in transaction.orders:
312
            order.status = OrderStatus.PAYMENT_FAILED
2339 chandransh 313
            order.statusDescription = "Payment Failed"
4247 rajveer 314
    elif new_status == TransactionStatus.AUTHORIZED or new_status == TransactionStatus.FLAGGED:
690 chandransh 315
        for order in transaction.orders:
4247 rajveer 316
            if new_status == TransactionStatus.AUTHORIZED:
317
                order.status = OrderStatus.SUBMITTED_FOR_PROCESSING
318
                order.statusDescription = "Submitted to warehouse"
319
            elif new_status == TransactionStatus.FLAGGED:
320
                order.status = OrderStatus.PAYMENT_FLAGGED
321
                order.statusDescription = "Payment flagged by gateway"
3092 chandransh 322
            order.cod = False
5527 anupam.sin 323
            order.orderType = orderType
743 rajveer 324
            #After we got payment success, we will set logistics info also 
325
            logistics_client = LogisticsClient().get_client()
326
            #FIXME line item is only one now. If multiple will come, need to fix.
871 chandransh 327
            item_id = order.lineitems[0].item_id
5767 rajveer 328
            logistics_info = logistics_client.getLogisticsInfo(order.customer_pincode, item_id, DeliveryType.PREPAID, pickUp)
743 rajveer 329
 
1730 ankur.sing 330
            current_time = datetime.datetime.now()
331
            logistics_info.deliveryTime = adjust_delivery_time(current_time, logistics_info.deliveryTime)
4009 chandransh 332
            logistics_info.shippingTime = adjust_delivery_time(current_time, logistics_info.shippingTime)
6726 rajveer 333
            logistics_info.deliveryDelay = adjust_delivery_time(current_time, (logistics_info.shippingTime+logistics_info.deliveryDelay))
5110 mandeep.dh 334
 
6525 rajveer 335
            order.otg = logistics_info.otgAvailable
743 rajveer 336
            order.warehouse_id = logistics_info.warehouseId
5110 mandeep.dh 337
            order.fulfilmentWarehouseId = logistics_info.fulfilmentWarehouseId
743 rajveer 338
            order.logistics_provider_id = logistics_info.providerId
339
            order.airwaybill_no = logistics_info.airway_billno
340
            order.tracking_id = order.airwaybill_no
6726 rajveer 341
            order.courier_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryDelay)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
4019 chandransh 342
            order.expected_shipping_time = (current_time + datetime.timedelta(days=logistics_info.shippingTime)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
4102 chandransh 343
            order.promised_shipping_time = order.expected_shipping_time
5165 rajveer 344
            order.expected_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryTime)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
3986 chandransh 345
            order.promised_delivery_time = order.expected_delivery_time 
871 chandransh 346
 
6718 rajveer 347
            if order.pickupStoreId:
348
                order.otg = False
349
 
5944 mandeep.dh 350
            inventory_client = InventoryClient().get_client()
5966 rajveer 351
            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)
1351 varun.gupt 352
 
4316 anupam.sin 353
            try:
5944 mandeep.dh 354
                item_pricing = inventory_client.getItemPricing(item_id, -1)
4316 anupam.sin 355
                order.lineitems[0].transfer_price = item_pricing.transferPrice
6751 amar.kumar 356
                order.lineitems[0].nlc = item_pricing.nlc
4316 anupam.sin 357
            except:
358
                print "Not able to get transfer price. Skipping"
5944 mandeep.dh 359
 
360
            catalog_client = CatalogClient().get_client() 
5508 rajveer 361
            voucherAmount = catalog_client.getVoucherAmount(item_id, VoucherType.SPICEDECK_MOBILE)
362
            if voucherAmount:
5514 rajveer 363
                __create_recharge_voucher_tracker(order, voucherAmount, VoucherType.SPICEDECK_MOBILE)
5508 rajveer 364
 
3064 chandransh 365
    elif new_status == TransactionStatus.COD_IN_PROCESS:
366
        for order in transaction.orders:
4662 rajveer 367
            order.status = OrderStatus.COD_VERIFICATION_PENDING
3064 chandransh 368
            order.statusDescription = "Verification Pending"
369
            order.cod = True
5527 anupam.sin 370
            order.orderType = orderType
3064 chandransh 371
            #After we got payment success, we will set logistics info also 
372
            logistics_client = LogisticsClient().get_client()
373
            #FIXME line item is only one now. If multiple will come, need to fix.
374
            item_id = order.lineitems[0].item_id
5555 rajveer 375
            if order.pickupStoreId:
5885 mandeep.dh 376
                # Need to send prepaid awb number for store pick up orders
377
                logistics_info = logistics_client.getLogisticsEstimation(item_id, order.customer_pincode, DeliveryType.COD)
378
                prepaid_logistics_info = logistics_client.getLogisticsInfo(order.customer_pincode, item_id, DeliveryType.PREPAID, pickUp)
379
                logistics_info.airway_billno = prepaid_logistics_info.airway_billno
380
                logistics_info.providerId = prepaid_logistics_info.providerId
6525 rajveer 381
                # Will not provide OTG in pickup store
382
                order.otg = False
5555 rajveer 383
            else:
5767 rajveer 384
                logistics_info = logistics_client.getLogisticsInfo(order.customer_pincode, item_id, DeliveryType.COD, pickUp)
6525 rajveer 385
                order.otg = logistics_info.otgAvailable
7293 anupam.sin 386
 
3064 chandransh 387
            current_time = datetime.datetime.now()
388
            logistics_info.deliveryTime = adjust_delivery_time(current_time, logistics_info.deliveryTime)
4009 chandransh 389
            logistics_info.shippingTime = adjust_delivery_time(current_time, logistics_info.shippingTime)
6726 rajveer 390
            logistics_info.deliveryDelay = adjust_delivery_time(current_time, (logistics_info.shippingTime+logistics_info.deliveryDelay))
391
 
3064 chandransh 392
            order.warehouse_id = logistics_info.warehouseId
5110 mandeep.dh 393
            order.fulfilmentWarehouseId = logistics_info.fulfilmentWarehouseId
3064 chandransh 394
            order.logistics_provider_id = logistics_info.providerId
395
            order.airwaybill_no = logistics_info.airway_billno
396
            order.tracking_id = order.airwaybill_no
6726 rajveer 397
            order.courier_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryDelay)).replace(hour=COD_SHIPPING_CUTOFF_TIME, minute=0, second=0)
4019 chandransh 398
            order.expected_shipping_time = (current_time + datetime.timedelta(days=logistics_info.shippingTime)).replace(hour=COD_SHIPPING_CUTOFF_TIME, minute=0, second=0)
4102 chandransh 399
            order.promised_shipping_time = order.expected_shipping_time
5165 rajveer 400
            order.expected_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryTime)).replace(hour=COD_SHIPPING_CUTOFF_TIME, minute=0, second=0)
3986 chandransh 401
            order.promised_delivery_time = order.expected_delivery_time
3064 chandransh 402
 
5944 mandeep.dh 403
            inventory_client = InventoryClient().get_client()
5966 rajveer 404
            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)
3064 chandransh 405
 
4316 anupam.sin 406
            try:
5944 mandeep.dh 407
                item_pricing = inventory_client.getItemPricing(item_id, -1)
6751 amar.kumar 408
                order.lineitems[0].transfer_price = item_pricing.transferPrice
409
                order.lineitems[0].nlc = item_pricing.nlc        
4316 anupam.sin 410
            except:
411
                print "Not able to get transfer price. Skipping"
5508 rajveer 412
 
5944 mandeep.dh 413
            catalog_client = CatalogClient().get_client()
5508 rajveer 414
            voucherAmount = catalog_client.getVoucherAmount(item_id, VoucherType.SPICEDECK_MOBILE)
415
            if voucherAmount:
5514 rajveer 416
                __create_recharge_voucher_tracker(order, voucherAmount, VoucherType.SPICEDECK_MOBILE)
483 rajveer 417
    session.commit()
3499 mandeep.dh 418
 
3530 mandeep.dh 419
    try:
7308 rajveer 420
        if order.source == OrderSource.WEBSITE:    
421
            if new_status == TransactionStatus.COD_IN_PROCESS:
422
                transaction_requiring_extra_processing = TransactionRequiringExtraProcessing()
423
                transaction_requiring_extra_processing.category = 'COD_VERIFICATION'
424
                transaction_requiring_extra_processing.transaction_id = transaction_id
425
                session.commit()
426
            elif new_status == TransactionStatus.FLAGGED:
427
                transaction_requiring_extra_processing = TransactionRequiringExtraProcessing()
428
                transaction_requiring_extra_processing.category = 'PAYMENT_FLAGGED'
429
                transaction_requiring_extra_processing.transaction_id = transaction_id
430
                session.commit()
7313 rajveer 431
        elif order.source == OrderSource.STORE:
7386 anupam.sin 432
 
7313 rajveer 433
                catalog_client = CatalogClient().get_client() 
434
                sourcePricing = catalog_client.getStorePricing(order.lineitems[0].item_id)
435
                if order.total_amount >= sourcePricing.minPrice:
436
                    order.status = OrderStatus.SUBMITTED_FOR_PROCESSING
7386 anupam.sin 437
                    order.statusDescription = "Order Accepted"
7344 rajveer 438
                    session.commit()
7386 anupam.sin 439
                    __push_store_collection_to_hotspot(order, "advance", order.advanceAmount)
7344 rajveer 440
 
7313 rajveer 441
                else: 
442
                    order.status = OrderStatus.COD_VERIFICATION_PENDING
7386 anupam.sin 443
                    order.statusDescription = "Approval Pending"
7313 rajveer 444
                    content = "<html><body>"
7350 rajveer 445
                    content += "<h4>Order Id:  " + str(order.id) + "</h4>"
446
                    content += "<h4>Product:  " + str(order.lineitems[0]) + "</h4>"
447
                    content += "<h4>Min Price: " +  str(sourcePricing.minPrice) + "</h4>"
448
                    content += "<h4>Recommended Price: " +  str(sourcePricing.recommendedPrice) + "</h4>"
7313 rajveer 449
                    content += "<h2>Approval Requested for Price: " +  str(order.total_amount) + "</h2>"
7350 rajveer 450
                    content += "<h2><a href='http://support.shop2020.in:8080/Support/price-approval?xszbg=" + base64.b64encode(str(order.id))  + "'>Click here for Approval</a></h2>"
7313 rajveer 451
                    content += "<br><br></body></html>"
452
                    store = get_hotspot_store(order.storeId, "")
453
                    helper_client = HelperClient().get_client()
7391 rajveer 454
                    helper_client.saveUserEmailForSending(store.approvalEmail.split(';'), "", "Price approval requested for " + str(order.lineitems[0]) + " order Id " + str(order.id) + " in store " + store.hotspotId , content, str(transaction_id), "PriceApproval", [], [])
7344 rajveer 455
                    session.commit()
3530 mandeep.dh 456
    except Exception as e:
4065 mandeep.dh 457
        print "Error inserting transaction Id: " + str(transaction_id) + " due to " + str(e)
3499 mandeep.dh 458
 
483 rajveer 459
    return True
460
 
5514 rajveer 461
def __create_recharge_voucher_tracker(order, amount, voucherType):
5508 rajveer 462
    rvt = RechargeVoucherTracker()
463
    rvt.order = order
464
    rvt.amount = amount
465
    rvt.voucherIssued = False
5514 rajveer 466
    rvt.voucherType = voucherType
5508 rajveer 467
 
3994 chandransh 468
def __get_holidays(start_time=0L, to_time=-1L):
469
    '''
470
    Get the list of all public holidays since start time including the
471
    day of start time if it's a holiday
472
    '''
473
    midnightTime = start_time.replace(hour=0, minute=0, second=0, microsecond=0)
1730 ankur.sing 474
    fromDate = to_java_date(midnightTime)
475
    logistics_client = LogisticsClient().get_client()
3994 chandransh 476
    #TODO: This list should be cached after the first call.
477
    #Calling logistics server is also unnecessary.
478
    holidays = logistics_client.getHolidays(fromDate, to_time)
479
    holidays = [to_py_date(holiday).date() for holiday in holidays]
480
    return holidays
481
 
482
def adjust_delivery_time(start_time, delivery_days):
483
    '''
484
    Returns the actual no. of days which will pass while 'delivery_days'
485
    no. of business days will pass since 'order_time'. 
486
    '''
487
    start_date = start_time.date()
488
    end_date = start_date + datetime.timedelta(days = delivery_days)
489
    holidays = __get_holidays(start_time)
1730 ankur.sing 490
 
3994 chandransh 491
    while start_date <= end_date:
492
        if start_date.weekday() == 6 or start_date in holidays:
1730 ankur.sing 493
            delivery_days = delivery_days + 1
3994 chandransh 494
            end_date = end_date + datetime.timedelta(days = 1)
4088 chandransh 495
        start_date = start_date + datetime.timedelta(days = 1)
3994 chandransh 496
 
1730 ankur.sing 497
    return delivery_days
498
 
6561 amit.gupta 499
def get_business_days_count(start_time, end_time):
500
    '''
501
    Returns business dates between two dates
502
    '''
503
    start_date = start_time.date()
504
    end_date  = end_time.date()
6669 amit.gupta 505
    diff = (end_date - start_date).days
6665 amit.gupta 506
    sundays = diff/7 + 1 if (start_date.weekday() + (diff%7) > 6) else diff/7 
6561 amit.gupta 507
    '''holidays = __get_holidays(start_time, end_time)'''
508
    logistics_client = LogisticsClient().get_client()
509
    #TODO: This list should be cached after the first call.
510
    #Calling logistics server is also unnecessary.
511
    holidays = logistics_client.getHolidays(to_java_date(start_time), to_java_date(end_time))
512
    non_business_days = len(holidays)
513
    for holiday in holidays:
6675 rajveer 514
        pyholiday = to_py_date(holiday).date()
515
        if pyholiday.weekday() == 6:
6561 amit.gupta 516
            sundays = sundays - 1
517
    return diff - (non_business_days + sundays)
518
 
519
 
1398 varun.gupt 520
def enqueue_transaction_info_email(transaction_id):
1262 varun.gupt 521
    transaction = get_transaction(transaction_id)
6650 amit.gupta 522
    subject = source_name + " - Order Details"
523
    otgLink = ""
6660 amit.gupta 524
    inOrderOtg = "<div>On Time Guarantee<br><span style=color:red>We pay if we delay</span></div>"
6650 amit.gupta 525
    if len(transaction.orders) == 1:
526
        inOrderOtg = ""
527
        if transaction.orders[0].otg :
528
            subject = "Your Order is confirmed with On Time Guarantee We Pay if we Delay"
529
            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>'
530
 
5793 rajveer 531
    customer_name = "" 
1262 varun.gupt 532
    html_header = """
533
<html>
534
<body>
535
<div>
536
    <p>
5793 rajveer 537
        Hello $customer_name,<br /><br />
6650 amit.gupta 538
        Thanks for placing order with us.$otgLink Following are the details of your order:
1262 varun.gupt 539
    </p>
540
    <div>
541
        Order Date: $order_date
1569 varun.gupt 542
    </div>
1262 varun.gupt 543
    <div>
544
        <table>
5879 rajveer 545
        <tr><td colspan="6"><hr /></td></tr>
546
        <tr><td colspan="6" align="left"><b>Order Details</b></td></tr>
547
        <tr><td colspan="6"><hr /></td></tr>
1262 varun.gupt 548
        <tr>
2050 varun.gupt 549
            <th width="100">Order No.</th>
550
            <th>Product</th>
5879 rajveer 551
            <th width="100">Estimated Delivery Date</th>
2050 varun.gupt 552
            <th width="100">Quantity</th>
553
            <th width="100">Unit Price</th>
554
            <th width="100">Amount</th>
1262 varun.gupt 555
        </tr>
556
    """
1398 varun.gupt 557
    user_email = ""
1262 varun.gupt 558
    total_amount = 0.0
559
    html_table = ""
1569 varun.gupt 560
    order_date = datetime.datetime.now()
5676 rajveer 561
 
562
    orders = transaction.orders
563
    html_pickup_text = ""
564
    random_text = ""
5697 rajveer 565
    if orders[0].pickupStoreId:
5793 rajveer 566
        random_text = str(randrange(100000, 999999)) 
6650 amit.gupta 567
 
6654 amit.gupta 568
    first = True    
5676 rajveer 569
    for order in orders:
5793 rajveer 570
        customer_name = order.customer_name
1262 varun.gupt 571
        order_date = order.created_timestamp
1398 varun.gupt 572
        user_email = order.customer_email
6654 amit.gupta 573
        if first:
574
            first = False
575
            html_tr = "" 
576
        else:
6659 amit.gupta 577
            html_tr =  "<tr><td colspan=6>&nbsp;</td></tr>"
6654 amit.gupta 578
        html_tr += "<tr><td align='center'>" + str(order.id) + "</td>"
5676 rajveer 579
 
5879 rajveer 580
        sdt = datetime.datetime.strptime(str(orders[0].expected_delivery_time), "%Y-%m-%d %H:%M:%S")
581
        store_delivery_date = sdt.strftime("%d %B %Y")
582
 
5676 rajveer 583
        if order.pickupStoreId:
584
            attribute = Attribute()
585
            attribute.orderId = order.id
586
            attribute.name = "SECRET_CODE"
587
            attribute.value = random_text
588
            session.commit()
1262 varun.gupt 589
 
590
        for lineitem in order.lineitems:
2050 varun.gupt 591
            lineitem_total_price = round(lineitem.total_price, 2)
592
 
1276 chandransh 593
            html_tr += "<td>" + str(lineitem) + "</td>"
6561 amit.gupta 594
            if order.otg:
6650 amit.gupta 595
                html_tr += "<td align='center'><div>" + store_delivery_date + "</div>" + inOrderOtg + "</td>"
6561 amit.gupta 596
            else:
597
                html_tr += "<td align='center'>" + store_delivery_date + "</td>"
2050 varun.gupt 598
            html_tr += "<td align='center'>" + ("%.0f" % lineitem.quantity) + "</td>"
599
            html_tr += "<td align='center'> Rs. " + ("%.2f" % lineitem.unit_price) + "</td>"
600
            html_tr += "<td align='center'> Rs. " + ("%.2f" % lineitem_total_price) + "</td></tr>"
601
            total_amount += lineitem_total_price
1262 varun.gupt 602
            html_table += html_tr
7190 amar.kumar 603
        if order.freebieItemId:
604
            catalog_client = CatalogClient().get_client()
605
            item = catalog_client.getItem(order.freebieItemId)
7201 amar.kumar 606
            html_table += "<tr><td align='center'></td><td style='font-style:italic;' colspan='5'> Free Item: "+item.brand + " " + item.modelName + " " + item.modelNumber+"</td></tr>"
6906 rajveer 607
        if order.insurer:
608
            html_table += "<tr><td colspan=6>&nbsp;</td></tr>"
6927 rajveer 609
            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>"
6911 rajveer 610
            html_table += "<td align='center'>" + str(order.insuranceAmount) + "</td></tr>"
6927 rajveer 611
            total_amount += order.insuranceAmount
6422 rajveer 612
    emi_amount = 0
613
    miscCharges = get_misc_charges(transaction_id)
614
    if miscCharges.get(1):
615
        emi_amount = miscCharges.get(1)
616
 
1262 varun.gupt 617
    html_footer = """
5879 rajveer 618
        <tr><td colspan=6>&nbsp;</td></tr>
619
        <tr><td colspan=6><hr /></td></tr>
6422 rajveer 620
        """
621
    if emi_amount > 0:
6715 amit.gupta 622
        total_amount += emi_amount
6422 rajveer 623
        html_footer = html_footer + "<tr>\
624
                        <td colspan=5>EMI Processing Charges</td>\
625
                        <td> Rs. $emi_amount</td>\
626
                    </tr>"
627
 
628
    html_footer = html_footer + "<tr>\
629
                <td colspan=5>Total Amount</td>\
630
                <td> Rs. $total_amount</td>\
631
                </tr>\
632
            </table>\
633
        </div>"
5793 rajveer 634
 
6422 rajveer 635
 
5793 rajveer 636
    store_address = ""
637
    if orders[0].pickupStoreId:
638
        store = LogisticsClient().get_client().getPickupStore(orders[0].pickupStoreId)
639
        store_address = __get_store_address_html(store)
640
 
641
        html_pickup_text = html_pickup_text + """
642
        <h3>Steps to Pickup In Store</h3>
5879 rajveer 643
        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>
5793 rajveer 644
        <br><i>$store_address</i><br>
645
        """
646
 
647
        if orders[0].cod:
648
            html_pickup_text = html_pickup_text + """
6318 rajveer 649
            2) Pay Rs. $net_amount, present a valid Photo Identity Proof* and use your Secret Code <b><i>$secret_code</i></b> to claim your Product(s).<br><br>
5793 rajveer 650
            *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>
651
            <br>
6029 rajveer 652
            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>
5793 rajveer 653
            </br><hr />
654
            """
655
        else:
656
            html_pickup_text = html_pickup_text + """
5879 rajveer 657
            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>
5793 rajveer 658
            *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>
659
            <br>
6029 rajveer 660
            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>
5793 rajveer 661
            </br><hr />
662
            """
663
 
5676 rajveer 664
    html_footer = html_footer + html_pickup_text + """
1262 varun.gupt 665
    <p>
666
        Best Wishes,<br />
6029 rajveer 667
        $source_name Team
1262 varun.gupt 668
    </p>
669
</div>
670
</body>
671
</html>
672
    """
1398 varun.gupt 673
 
1569 varun.gupt 674
    dt = datetime.datetime.strptime(str(order_date), "%Y-%m-%d %H:%M:%S")
1565 varun.gupt 675
    formated_order_date = dt.strftime("%A, %d. %B %Y %I:%M%p")
5793 rajveer 676
 
677
    sdt = datetime.datetime.strptime(str(orders[0].expected_delivery_time), "%Y-%m-%d %H:%M:%S")
678
    store_delivery_date = sdt.strftime("%A, %d %B %Y")
679
 
6650 amit.gupta 680
    email_header = Template(html_header).substitute(dict(order_date = formated_order_date, customer_name = customer_name, source_url = source_url, otgLink = otgLink))
6422 rajveer 681
    email_footer = Template(html_footer).substitute(dict(total_amount = "%.2f" % total_amount, emi_amount = "%.2f" % emi_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))
1565 varun.gupt 682
 
1351 varun.gupt 683
    try:
684
        helper_client = HelperClient().get_client()
6906 rajveer 685
        helper_client.saveUserEmailForSending([user_email], "", subject, email_header + html_table + email_footer, str(transaction_id), "TransactionInfo", [], [])
5866 rajveer 686
 
1351 varun.gupt 687
        return True
688
    except Exception as e:
689
        print e
690
        return False
1262 varun.gupt 691
 
5802 rajveer 692
def enqueue_received_at_store_email(order):
693
    html_header = """
694
    <html>
695
    <body>
696
    <div>
697
        <p>
698
            Hello $customer_name,<br /><br />
699
            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:
700
        </p>
701
        <div>
702
            Order Date: $order_date
703
        </div>
704
        <div>
705
            <table>
706
            <tr><td colspan="5"><hr /></td></tr>
707
            <tr><td colspan="5" align="left"><b>Order Details</b></td></tr>
708
            <tr><td colspan="5"><hr /></td></tr>
709
            <tr>
710
                <th width="100">Order No.</th>
711
                <th>Product</th>
712
                <th width="100">Quantity</th>
713
                <th width="100">Unit Price</th>
714
                <th width="100">Amount</th>
715
            </tr>
716
    """
717
    total_amount = 0.0
718
    html_table = ""
719
 
720
    html_pickup_text = ""
721
    random_text = __get_secret_code(order.id)
722
 
723
    customer_name = order.customer_name
724
    order_date = order.created_timestamp
725
    user_email = order.customer_email
726
    html_tr = "<tr><td align='center'>" + str(order.id) + "</td>"
727
 
728
    for lineitem in order.lineitems:
729
        lineitem_total_price = round(lineitem.total_price, 2)
730
 
731
        html_tr += "<td>" + str(lineitem) + "</td>"
732
        html_tr += "<td align='center'>" + ("%.0f" % lineitem.quantity) + "</td>"
733
        html_tr += "<td align='center'> Rs. " + ("%.2f" % lineitem.unit_price) + "</td>"
734
        html_tr += "<td align='center'> Rs. " + ("%.2f" % lineitem_total_price) + "</td></tr>"
735
        total_amount += lineitem_total_price
736
        html_table += html_tr
737
 
738
    html_footer = """
739
        <tr><td colspan=5>&nbsp;</td></tr>
740
        <tr><td colspan=5><hr /></td></tr>
741
        <tr>
742
            <td colspan=4>Total Amount</td>
743
            <td> Rs. $total_amount</td>
744
        </tr>
745
        </table>
746
    </div>
747
    """
748
 
749
    store_address = ""
750
    if order.pickupStoreId:
751
        store = LogisticsClient().get_client().getPickupStore(order.pickupStoreId)
752
        store_address = __get_store_address_html(store)
753
 
754
        html_pickup_text = html_pickup_text + """
755
        <h3>Steps to Pickup In Store</h3>
756
        1) Please visit the following store selected by you on or before $order_expiry_date<br>
757
        <br><i>$store_address</i><br>
758
        """
759
 
760
        if order.cod:
761
            html_pickup_text = html_pickup_text + """
6318 rajveer 762
            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>
5802 rajveer 763
            *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>
764
            <br>
6029 rajveer 765
            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>
5802 rajveer 766
            </br><hr />
767
            """
768
        else:
769
            html_pickup_text = html_pickup_text + """
770
            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>
771
            *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>
772
            <br>
6029 rajveer 773
            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>
5802 rajveer 774
            </br><hr />
775
            """
776
 
777
        html_footer = html_footer + html_pickup_text + """
778
        <p>
779
            Best Wishes,<br />
6029 rajveer 780
            $source_name Team
5802 rajveer 781
        </p>
782
        </div>
783
        </body>
784
        </html>
785
        """
786
 
787
    subject = "Your order for " + str(order.lineitems[0]) + " is ready for Pickup in Store"
788
    dt = datetime.datetime.strptime(str(order_date), "%Y-%m-%d %H:%M:%S")
789
    formated_order_date = dt.strftime("%A, %d. %B %Y %I:%M%p")
790
 
791
    oetd = datetime.datetime.now() + datetime.timedelta(days=4)
792
    formated_order_expiry_date = oetd.strftime("%A, %d %B %Y")
793
 
794
 
6029 rajveer 795
    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))
6318 rajveer 796
    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))
5802 rajveer 797
 
798
    try:
5812 rajveer 799
        helper_client = HelperClient(host_key = "helper_service_server_host_prod").get_client()
6280 rajveer 800
        helper_client.saveUserEmailForSending([user_email], "", subject, email_header + html_table + email_footer, str(order.id), "ReceivedAtStore", [], [])
5802 rajveer 801
        return True
802
    except Exception as e:
803
        print e
804
        return False
805
 
5966 rajveer 806
def enqueue_delivery_success_mail(order):
5807 rajveer 807
    html_header = """
808
    <html>
809
    <body>
810
    <div>
811
        <p>
812
            Dear $customer_name,<br /><br />
813
    """
6561 amit.gupta 814
 
5807 rajveer 815
    if order.pickupStoreId:
816
        pickup_text = "Pickup Date: " + order.delivery_timestamp.strftime("%A, %d. %B %Y %I:%M%p")
817
        thank_you_html = """
818
        Thank you for shopping with us and picking up your order in Store. Please do join us at our <a href="http://www.facebook.com/mysaholic">Facebook Page</a>, and share your experience with other shoppers.<br><br>
819
 
6029 rajveer 820
        Following are the details of your order for which the pickup has happened. If you have not picked up this product please <a href="$source_url/contact-us" target="_blank">contact us</a> immediately.<br>
5807 rajveer 821
        """
822
    else:
823
        pickup_text = ""
6561 amit.gupta 824
        if order.otg:
825
 
826
            delayed = False
827
            fda = False
828
 
829
            if order.first_dlvyatmp_timestamp.date() < order.delivery_timestamp.date():
830
                fda = True
831
 
832
            fda_datetime = order.first_dlvyatmp_timestamp            
833
            fda_date = fda_datetime.date()
834
 
6711 amit.gupta 835
            if order.promised_delivery_time.date() < fda_date:
6561 amit.gupta 836
                delayed = True
837
 
838
            if not delayed and not fda:
839
                thank_you_html = """As Promised """ + str(order.lineitems[0]) +""" ordered by you has been <b>Delivered On Time.</b>""" 
840
            elif delayed:
841
                max_discount = 500
6711 amit.gupta 842
                delayedDays = get_business_days_count(order.promised_delivery_time, fda_datetime)
6561 amit.gupta 843
                max_discount = min(max_discount, order.lineitems[0].unit_price/10)
6686 anupam.sin 844
                discount = min(round(max_discount),delayedDays*50)  
6561 amit.gupta 845
                promotion_client = PromotionClient().get_client()
846
                endOn =  order.delivery_timestamp + datetime.timedelta(days = 30)
7347 amit.gupta 847
                expiry = endOn.strftime("%A, %d. %B %Y")
6561 amit.gupta 848
                endOn = to_java_date(endOn)
6688 anupam.sin 849
                arguments = "{\"endOn\":" + str(endOn) + ", \"emails\":[\"" + order.customer_email + "\"], \"couponType\":\"both\", \"usage_limit_for_user\":1, \"isCod\":False, \"discount\":" + str(discount) + "}"
6742 anupam.sin 850
                otgCoupon = promotion_client.createCoupon(28, '', arguments, False, "otg")
7347 amit.gupta 851
                thank_you_html = '$prodName ordered by you has been delivered. We apologise for a delay of $delayedDays business days.<br><br> As per our <b>On Time Guarantee</b> Please accept a Gift Voucher worth <b>Rs.$discount</b> as a token of our apology. <br><br>Your unique Gift Voucher Code is <b>$otgCoupon</b>. <br><br>You can use the same to buy any Mobile, Camera, Laptop, Tablet, Accessory or Mobile/DTH Recharge from our website.<br> Note:GV is valid till $expiry<br>'
852
                thank_you_html = Template(thank_you_html).substitute(dict(prodName=order.lineitems[0], delayedDays = delayedDays, discount = discount, otgCoupon = otgCoupon, expiry = expiry))
6561 amit.gupta 853
            elif fda:
854
                fdaFormattedString = order.first_dlvyatmp_timestamp.strftime("%A, %d. %B %Y")
855
                thank_you_html = str(order.lineitems[0]) + """ ordered by you has been delivered.  The First Delivery attempt was made on """+ fdaFormattedString +""" , within our commited estimated time for delivery.""" 
856
 
857
            thank_you_html = thank_you_html + """If you are happy with our services please join us on <a href="http://www.facebook.com/mysaholic">Facebook</a>/<a href="https://twitter.com/saholic">Twitter</a> and help us spread the word."""  
858
 
859
        else :
860
            thank_you_html = str(order.lineitems[0]) + """ ordered by you has been delivered. 
861
            Thank you for shopping with us. Please do join us at our <a href="http://www.facebook.com/mysaholic">Facebook Page</a>, and share your experience with other shoppers. Following are the details of your order.<br>
7198 amar.kumar 862
            """
863
 
864
    freebie_text = "<br/>"
865
    if order.freebieItemId:
866
        catalog_client = CatalogClient().get_client()
867
        item = catalog_client.getItem(order.freebieItemId)
868
        freebie_text = freebie_text = "We have also delivered " + item.brand + " " + item.modelName + "" + item.modelNumber +" as promised"
869
    else:
870
        freebie_orderId = get_order_attribute_value(order.id, "freebieOrderId")
871
        if freebie_orderId != "":
872
            line_items = get_line_items_for_order(int(freebie_orderId))
873
            freebie_order = get_order(int(freebie_orderId))
874
            freebie_text = freebie_text + " We wish to inform you that your freebie item " +line_items[0].brand + " " + line_items[0].model_name + " " + line_items[0].model_number + " will be sent as a separate order with OrderId : " + freebie_orderId + " and is expected to be delivered on " + freebie_order.expected_delivery_time.strftime("%A, %d %B %Y")+ "<br/>You can track the status of this order from My Orders section in saholic.com" 
5807 rajveer 875
 
876
    html_header = html_header + thank_you_html + """        
877
        </p>
878
        <div>
879
            Order Date: $order_date <br>
880
            $pickup_text
881
        </div>
882
        <div>
883
            <table>
884
            <tr><td colspan="5"><hr /></td></tr>
885
            <tr><td colspan="5" align="left"><b>Order Details</b></td></tr>
886
            <tr><td colspan="5"><hr /></td></tr>
887
            <tr>
888
                <th width="100">Order No.</th>
889
                <th>Product</th>
890
                <th width="100">Quantity</th>
891
                <th width="100">Unit Price</th>
892
                <th width="100">Amount</th>
893
            </tr>
894
    """
895
    total_amount = 0.0
896
    html_table = ""
5802 rajveer 897
 
5807 rajveer 898
    customer_name = order.customer_name
899
    order_date = order.created_timestamp
900
    user_email = order.customer_email
901
    html_tr = "<tr><td align='center'>" + str(order.id) + "</td>"
902
 
903
    for lineitem in order.lineitems:
904
        lineitem_total_price = round(lineitem.total_price, 2)
905
 
906
        html_tr += "<td>" + str(lineitem) + "</td>"
907
        html_tr += "<td align='center'>" + ("%.0f" % lineitem.quantity) + "</td>"
908
        html_tr += "<td align='center'> Rs. " + ("%.2f" % lineitem.unit_price) + "</td>"
909
        html_tr += "<td align='center'> Rs. " + ("%.2f" % lineitem_total_price) + "</td></tr>"
910
        total_amount += lineitem_total_price
911
        html_table += html_tr
6906 rajveer 912
    if order.insurer:
6915 anupam.sin 913
        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>"
6911 rajveer 914
        html_table += "<td align='center'>" + str(order.insuranceAmount) + "</td></tr>"
6947 rajveer 915
        html_table += "<tr><td align='center'></td><td style='font-style:italic;'>Please download and read attached policy document.</td><td align='center'></td><td align='center'></td></tr>"
6906 rajveer 916
        total_amount += order.insuranceAmount
917
 
5807 rajveer 918
    html_footer = """
919
        <tr><td colspan=5>&nbsp;</td></tr>
920
        <tr><td colspan=5><hr /></td></tr>
921
        <tr>
922
            <td colspan=4>Total Amount</td>
923
            <td> Rs. $total_amount</td>
924
        </tr>
925
        </table>
7198 amar.kumar 926
        $freebie_text
5807 rajveer 927
    </div>
928
    <p>
929
        Best Wishes,<br />
6029 rajveer 930
        $source_name Team
5807 rajveer 931
    </p>
932
    </div>
933
    </body>
934
    </html>
935
    """
936
 
937
    subject = "Your order for " + str(order.lineitems[0]) + " is now complete"
938
    dt = datetime.datetime.strptime(str(order_date), "%Y-%m-%d %H:%M:%S")
939
    formated_order_date = dt.strftime("%A, %d. %B %Y %I:%M%p")
940
 
941
 
6029 rajveer 942
    email_header = Template(html_header).substitute(dict(order_date = formated_order_date, customer_name = customer_name, pickup_text = pickup_text, source_url = source_url))
7198 amar.kumar 943
    email_footer = Template(html_footer).substitute(dict(total_amount = "%.2f" % total_amount, source_name = source_name, freebie_text = freebie_text))
5807 rajveer 944
 
945
    try:
5812 rajveer 946
        helper_client = HelperClient(host_key = "helper_service_server_host_prod").get_client()
6957 rajveer 947
        if order.insurer:
948
            helper_client.saveUserEmailForSending([user_email], "", subject, email_header + html_table + email_footer, str(order.id), "DeliverySuccess", [], ["pramit.singh@shop2020.in ","anupam.singh@shop2020.in","rajveer.singh@shop2020.in"])
949
        else:
950
            helper_client.saveUserEmailForSending([user_email], "", subject, email_header + html_table + email_footer, str(order.id), "DeliverySuccess", [], [])
5807 rajveer 951
        return True
952
    except Exception as e:
953
        print e
954
        return False
955
 
5802 rajveer 956
def __get_secret_code(order_id):
5855 rajveer 957
    return get_order_attribute_value(order_id, 'SECRET_CODE')
5806 rajveer 958
 
5833 rajveer 959
def get_order_attribute_value(order_id, attribute_name):
5808 rajveer 960
    existingAttribute = Attribute.query.filter(Attribute.orderId == order_id).filter(Attribute.name == attribute_name).first()
961
    if existingAttribute:
962
        return existingAttribute.value
5802 rajveer 963
    return ""
5806 rajveer 964
 
6019 rajveer 965
def change_jacket_number(order_id, jacket_number):
966
    order = get_order(order_id)
967
    if order.status == OrderStatus.BILLED:
968
        order.jacket_number = jacket_number
6047 rajveer 969
        session.commit()
6019 rajveer 970
        return True
971
    return False
972
 
973
def mark_order_as_rto_in_transit(order_id):
974
    order = get_order(order_id)
6032 rajveer 975
    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]:
6019 rajveer 976
        return False
977
    order.status = OrderStatus.RTO_IN_TRANSIT
978
    order.delivery_timestamp = datetime.datetime.now()
7151 amit.gupta 979
    order.statusDescription = "Order Returned to Origin"
6019 rajveer 980
    update_trust_level(order)
6032 rajveer 981
    session.commit()
6019 rajveer 982
    return True
983
 
483 rajveer 984
def get_order(order_id):
985
    order = Order.get_by(id=order_id)
986
    if not order:
987
        raise TransactionServiceException(108, "no such order")
988
 
989
    return order
990
 
4999 phani.kuma 991
def get_order_list(order_ids):
992
    orders = Order.query.filter(Order.id.in_(tuple(order_ids)))
993
    return orders
994
 
5386 phani.kuma 995
def get_order_list_for_vendor(order_ids, vendor_id):
996
    if vendor_id == -1:
997
        return get_order_list(order_ids)
998
    else:
999
        orders = Order.query.filter_by(vendorId = vendor_id).filter(Order.id.in_(tuple(order_ids)))
1000
        return orders
1001
 
3014 chandransh 1002
def get_orders_for_customer(customer_id, from_date, to_date, statuses):
483 rajveer 1003
    if not customer_id:
1004
        raise TransactionServiceException(101, "bad customer id")
1005
    query = Order.query.filter(Order.customer_id == customer_id)
3014 chandransh 1006
    if statuses:
1007
        query = query.filter(Order.status.in_(tuple(statuses)))
483 rajveer 1008
    if from_date:
1009
        query = query.filter(Order.created_timestamp >from_date)
1010
    if to_date:
1011
        query = query.filter(Order.created_timestamp < to_date)
1012
    return query.all()
1013
 
1528 ankur.sing 1014
def get_order_for_customer(order_id, customer_id):
1015
    if not customer_id:
1016
        raise TransactionServiceException(101, "bad customer id")
1017
    order = get_order(order_id)
1018
    if order.customer_id != customer_id:
1019
        raise TransactionServiceException(108, "order: " + str(order_id) + " does not belong to customer: " + str(customer_id))
1020
    return order
1021
 
4801 anupam.sin 1022
def get_all_orders(statuses, from_date, to_date, warehouse_id):
1023
    if not len(statuses):
1024
        raise TransactionServiceException(101, "Status list is empty")
1025
    query = Order.query.filter(Order.status.in_(statuses))
1026
    if warehouse_id:
1027
        query = query.filter(Order.warehouse_id == warehouse_id)
1028
        #raise TransactionServiceException(101, "bad warehouse id")
483 rajveer 1029
    if from_date:
1030
        query = query.filter(Order.created_timestamp >from_date)
1031
    if to_date:
1032
        query = query.filter(Order.created_timestamp < to_date)
1033
    return query.all()
1034
 
4133 chandransh 1035
def get_orders_in_batch(statuses=[], offset=0, limit=0, warehouse_id=None):
4296 rajveer 1036
    query = Order.query
1037
    if warehouse_id:
1038
        query = query.filter(Order.warehouse_id == warehouse_id)
4133 chandransh 1039
    if statuses:
1040
        query = query.filter(Order.status.in_(statuses))
1041
    query = query.offset(offset)
1042
    if limit:
1043
        query = query.limit(limit)
1044
    return query.all()
1045
 
1046
def get_order_count(statuses=[], warehouse_id=None):
1047
    if not warehouse_id:
1048
        raise TransactionServiceException(101, "bad warehouse id")
1049
    query = session.query(func.count(Order.id)).filter(Order.warehouse_id == warehouse_id)
1050
    if statuses:
1051
        query = query.filter(Order.status.in_(statuses))
1052
    return query.scalar()
1053
 
1382 varun.gupt 1054
def get_returnable_orders_for_customer(customer_id, limit = None):
1055
    if not customer_id:
1056
        raise TransactionServiceException(101, "bad customer id")
1057
 
1058
    query = Order.query.filter(Order.customer_id == customer_id)
1059
    query = query.filter(Order.status != OrderStatus.PAYMENT_FAILED)
1060
    query = query.filter(Order.status != OrderStatus.REJECTED)
1061
    query = query.filter(Order.status > OrderStatus.SHIPPED_FROM_WH)
1062
    query = query.filter(or_(Order.status < OrderStatus.DELIVERY_SUCCESS, Order.delivery_timestamp < datetime.datetime.now() + datetime.timedelta(hours = 48)))
1063
    orders = query.all()
1064
    order_ids = [order.id for order in orders]
1065
    return order_ids
1066
 
1067
def get_cancellable_orders_for_customer(customer_id, limit = None):
1068
    if not customer_id:
1069
        raise TransactionServiceException(101, "bad customer id")
4815 phani.kuma 1070
    cancellableOrderStatuses = OrderStatusGroups().codCancellable
1382 varun.gupt 1071
    query = Order.query.filter(Order.customer_id == customer_id)
4815 phani.kuma 1072
    query = query.filter(Order.status.in_(cancellableOrderStatuses))
1382 varun.gupt 1073
    orders = query.all()
1074
    return [order.id for order in orders]
1075
 
995 varun.gupt 1076
def get_orders_by_billing_date(status, start_billing_date, end_billing_date, warehouse_id):
1077
    if not warehouse_id:
1078
        raise TransactionServiceException(101, "bad warehouse id")
1079
 
1080
    query = Order.query.filter(Order.warehouse_id == warehouse_id)
1081
 
1082
    if status:
1083
        query = query.filter(Order.status == status)
1084
 
1085
    if start_billing_date:
1086
        query = query.filter(Order.billing_timestamp >= start_billing_date)
1087
 
1088
    if end_billing_date:
1089
        query = query.filter(Order.billing_timestamp <= end_billing_date)
1090
 
1091
    return query.all()
1092
 
3451 chandransh 1093
def get_orders_by_shipping_date(from_shipping_date, to_shipping_date, provider_id, warehouse_id, cod):
1094
    query = Order.query.filter(Order.cod == cod)
3427 chandransh 1095
 
1096
    if warehouse_id and warehouse_id != -1:
1097
        query = query.filter(Order.warehouse_id == warehouse_id)
1098
 
1099
    if provider_id and provider_id != -1:
1100
        query = query.filter(Order.logistics_provider_id == provider_id)
1101
 
1102
    if from_shipping_date:
1103
        query = query.filter(Order.shipping_timestamp >= from_shipping_date)
1104
 
1105
    if to_shipping_date:
1106
        query = query.filter(Order.shipping_timestamp <= to_shipping_date)
1107
 
1108
    query = query.order_by(Order.airwaybill_no)
1109
 
1110
    return query.all()
1111
 
1528 ankur.sing 1112
def get_orders_for_transaction(transaction_id, customer_id):
1113
    orders = Order.query.filter_by(transaction_id=transaction_id, customer_id=customer_id).all()
1114
 
1208 chandransh 1115
    if not orders:
1116
        raise TransactionServiceException(101, "No order for the transaction")
1117
    return orders
1118
 
1405 ankur.sing 1119
def get_undelivered_orders(provider_id, warehouse_id):
1120
    query = Order.query
1121
    if provider_id != -1:
1122
        query = query.filter_by(Order.logistics_provider_id == provider_id)
1123
    if warehouse_id != -1:
1124
        query = query.filter(Order.warehouse_id == warehouse_id)
1125
    query = query.filter(and_(Order.status != OrderStatus.DELIVERY_SUCCESS, Order.status != OrderStatus.FAILED, \
1126
                              Order.status > OrderStatus.SHIPPED_FROM_WH))
1479 ankur.sing 1127
    #Get last midnight time instead of current time as courier company would have sent the 
1128
    #delivery records updated at least till midnight and not by the current time.
1129
    time_format = "%Y-%m-%d %H:%M:%S.%f"
1130
    t = time.strptime(str(datetime.datetime.now()), time_format)
1131
    midnightTime = datetime.datetime(*t[:3])
1132
    query = query.filter(Order.expected_delivery_time < midnightTime)
1405 ankur.sing 1133
    orders = query.all()
1134
    return orders
1135
 
1208 chandransh 1136
def get_line_items_for_order(order_id):
1137
    query = LineItem.query.filter(LineItem.order_id == order_id)
1138
    return query.all()
1139
 
483 rajveer 1140
def change_order_status(self, orderId, status, description):
1141
    order = get_order(orderId)
1142
    order.status = status
1143
    order.statusDescription = description
1144
    session.commit()
3578 mandeep.dh 1145
    update_trust_level(order)
1146
    return True
3499 mandeep.dh 1147
 
3578 mandeep.dh 1148
def update_trust_level(order):
3530 mandeep.dh 1149
    try:
3578 mandeep.dh 1150
        trust_level_delta = 0
1151
        if order.cod == True:
1152
            trust_level_delta = ORDER_STATUS_TO_USER_TRUST_LEVEL_DELTA_DICT.get(order.status, 0)
1153
 
3530 mandeep.dh 1154
        if (trust_level_delta != 0):
1155
            user_client = UserClient().get_client()
1156
            user_client.increaseTrustLevel(order.customer_id, trust_level_delta)
1157
    except Exception as e:
1158
        print e
3499 mandeep.dh 1159
 
483 rajveer 1160
    return True
3064 chandransh 1161
 
7391 rajveer 1162
def verify_order(orderId):
3064 chandransh 1163
    logging.info("Verifying order no: " + str(orderId))
1164
    order = get_order(orderId)
4662 rajveer 1165
    if order.status == OrderStatus.COD_VERIFICATION_PENDING:
3064 chandransh 1166
        order.status = OrderStatus.SUBMITTED_FOR_PROCESSING
1167
        order.statusDescription = "Submitted for processing"
1168
        order.verification_timestamp = datetime.datetime.now()
1169
        session.commit()
7344 rajveer 1170
        if order.source == OrderSource.STORE:
7391 rajveer 1171
            __push_store_collection_to_hotspot(order, 'advance', order.advanceAmount)
3064 chandransh 1172
        logging.info("Successfully verified order no: " + str(orderId))
1173
        return True
1174
    else:
1175
        logging.warning("Verify called for order no." + str(orderId) +" which is not in verification pending state");
1176
        return False
1177
 
4285 rajveer 1178
def accept_order(orderId):
3064 chandransh 1179
    logging.info("Accepting order no: " + str(orderId))
921 rajveer 1180
    order = get_order(orderId)
5110 mandeep.dh 1181
    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]:
3064 chandransh 1182
        if not order.cod:
1183
            if order.transaction.status == TransactionStatus.AUTHORIZED:
4421 mandeep.dh 1184
                __capture_txn(order)
3010 chandransh 1185
        order.status = OrderStatus.ACCEPTED
1186
        order.statusDescription = "Order Accepted"
1187
        order.accepted_timestamp = datetime.datetime.now()
5530 mandeep.dh 1188
        __amend_fulfilment_warehouse(order)
6789 rajveer 1189
        __update_transfer_price(order, order.fulfilmentWarehouseId)
3010 chandransh 1190
        session.commit()
3064 chandransh 1191
        logging.info("Successfully accepted the order no.:" + str(orderId))
3010 chandransh 1192
        return True
1193
    else:
3064 chandransh 1194
        logging.warning("Accept called for the unacceptable order: " + str(orderId))
3010 chandransh 1195
        return False
921 rajveer 1196
 
4421 mandeep.dh 1197
def __capture_txn(order):
1198
    txnId = order.transaction_id
3010 chandransh 1199
    logging.info("Capturing payment for merchant txn:" + str(txnId))
4421 mandeep.dh 1200
    try:
1201
        payment_client = PaymentClient().get_client()
1202
        capture_result = payment_client.capturePayment(txnId)
1203
        if capture_result:
1204
            logging.info("Successfully captured payment for merchant txn:" + str(txnId))
7293 anupam.sin 1205
            change_transaction_status(txnId, TransactionStatus.IN_PROCESS, "Payment received", PickUpType.COURIER, order.orderType, order.source)
4421 mandeep.dh 1206
        else:
1207
            raise TransactionServiceException(115, "Payment capture failed.")
1208
    except PaymentException as e:
1209
        if e.error_code == 106:
1210
            order.status = OrderStatus.CAPTURE_IN_PROCESS
1211
            session.commit()
1212
            raise TransactionServiceException(122, "Unable to capture payment due to connection issue.")
1213
        else:
1214
            raise TransactionServiceException(115, "Payment capture failed.")
3010 chandransh 1215
 
5530 mandeep.dh 1216
def __amend_fulfilment_warehouse(order):
1217
    itemId = order.lineitems[0].item_id
5944 mandeep.dh 1218
    inventoryClient = InventoryClient().get_client()
1219
    inventory = inventoryClient.getItemInventoryByItemId(itemId)
5530 mandeep.dh 1220
    if not (inventory.availability.has_key(order.fulfilmentWarehouseId) and inventory.availability[order.fulfilmentWarehouseId]):
5944 mandeep.dh 1221
        for warehouse in inventoryClient.getWarehouses(WarehouseType.OURS, InventoryType.GOOD, 0, order.warehouse_id, 0):
5558 mandeep.dh 1222
            if inventory.availability.has_key(warehouse.id) and inventory.availability[warehouse.id] >= inventory.reserved[warehouse.id] + order.lineitems[0].quantity:
5966 rajveer 1223
                inventoryClient.reduceReservationCount(itemId, order.fulfilmentWarehouseId, sourceId, order.id, order.lineitems[0].quantity)
1224
                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)
5637 mandeep.dh 1225
                order.fulfilmentWarehouseId = warehouse.id
5530 mandeep.dh 1226
                break
1227
 
7190 amar.kumar 1228
def add_billing_details(orderId, invoice_number, serialNumbers, itemNumbers, freebieWarehouseId, billedBy, jacketNumber, billingType, fulfilmentWarehouseId, authorize):
4285 rajveer 1229
    if jacketNumber is None or jacketNumber <= 0:
2783 chandransh 1230
        raise TransactionServiceException(110, "Invalid jacket number")
1231
 
4285 rajveer 1232
    if billedBy is None or billedBy.strip() == "":
2783 chandransh 1233
        raise TransactionServiceException(110, "Invalid Biller")
1234
 
1149 chandransh 1235
    order = Order.get_by(id=orderId)
1236
    if not order:
2783 chandransh 1237
        raise TransactionServiceException(101, "No order found for the given order id" + str(orderId))
5110 mandeep.dh 1238
 
7190 amar.kumar 1239
    '''
1240
    First checking whether freebie can be billed or not otherwise wont proceed.
1241
    '''
7198 amar.kumar 1242
    if order.freebieItemId:
1243
        if billingType == BillingType.OURS or billingType == BillingType.OURS_EXTERNAL:
1244
            if freebieWarehouseId:
7190 amar.kumar 1245
                try:
7198 amar.kumar 1246
                    inventory_client = InventoryClient().get_client()
1247
                    warehouse = inventory_client.getWarehouse(freebieWarehouseId)
1248
 
7199 amar.kumar 1249
                    if warehouse.warehouseType!= WarehouseType.OURS or warehouse.inventoryType != InventoryType.GOOD:
7198 amar.kumar 1250
                        raise TransactionServiceException(110,'Billing of Freebie is only allowed from OURS_GOOD warehouses ')
1251
 
7190 amar.kumar 1252
                    warehouse_client = WarehouseClient().get_client()
1253
                    inventoryItem = warehouse_client.scanfreebie(orderId, order.freebieItemId, freebieWarehouseId, ScanType.SALE);
1254
 
1255
                    attr = Attribute()
1256
                    attr.orderId = orderId
1257
                    attr.name = "freebie_tp"
1258
                    attr.value = str(inventoryItem.unitPrice)
1259
 
1260
                    attr1 = Attribute()
1261
                    attr1.orderId = orderId
1262
                    attr1.name = "freebie_vendor"
1263
                    attr1.value = str(inventoryItem.supplierId)
5966 rajveer 1264
 
7190 amar.kumar 1265
                    inventory_client = InventoryClient().get_client()
1266
                    item_pricing = inventory_client.getItemPricing(order.freebieItemId, warehouse.vendor.id)
1267
                    attr2 = Attribute()
1268
                    attr2.orderId = orderId
1269
                    attr2.name = "freebie_nlc"
1270
                    attr2.value = str(item_pricing.nlc)
1271
                except Exception as e:
1272
                    print sys.exc_info()[0]
1273
                    print e.message
7198 amar.kumar 1274
                    raise TransactionServiceException(110,'Error in billing freebie for warehouseId ' + str(freebieWarehouseId))
1275
            else:
1276
                raise TransactionServiceException(110,'No warehouseId provided for billing of freebie ')
1277
        else:
1278
            raise TransactionServiceException(110,'Order with freebies associated with it cant be billed from an external warehouse ')
5110 mandeep.dh 1279
    lineitem = order.lineitems[0]
1280
    item_id = lineitem.item_id
5966 rajveer 1281
 
6007 rajveer 1282
#    inventoryClient = InventoryClient().get_client()
1283
#    if not inventoryClient.isOrderBillable(item_id, order.fulfilmentWarehouseId, sourceId, orderId):
1284
#        raise TransactionServiceException(101, "There are other orders to be billed before this order id " + str(orderId))
5966 rajveer 1285
 
5110 mandeep.dh 1286
    catalog_client = CatalogClient().get_client()
1287
    item = catalog_client.getItem(item_id)
4283 anupam.sin 1288
    if order.status == OrderStatus.ACCEPTED:
4285 rajveer 1289
        order.jacket_number = jacketNumber
6751 amar.kumar 1290
 
1291
        if itemNumbers:
1292
            lineitem.item_number = itemNumbers[0]    
7180 rajveer 1293
        if serialNumbers:
1294
            lineitem.serial_number = serialNumbers[0]                
1295
 
6787 rajveer 1296
        '''
6751 amar.kumar 1297
        if billingType == BillingType.EXTERNAL or billingType == BillingType.OURS_EXTERNAL:
4763 rajveer 1298
            if billedOrdersColorMap.has_key(orderId):
1299
                etpColor = billedOrdersColorMap.get(orderId)
1300
                ourColor = order.lineitems[0].color
4781 rajveer 1301
                if ourColor and etpColor != ourColor and not authorize:
4763 rajveer 1302
                    raise TransactionServiceException(777, "ETP color: " + etpColor + " and Order color: " + ourColor)
1303
                else:
1304
                    billedOrdersColorMap.pop(orderId)
6787 rajveer 1305
        '''
6751 amar.kumar 1306
 
1307
        if billingType == BillingType.EXTERNAL:            
1308
            order.invoice_number = invoice_number
1309
 
1310
        if billingType == BillingType.OURS or billingType == BillingType.OURS_EXTERNAL:
6757 rajveer 1311
            if ItemType.SERIALIZED == item.type and not (serialNumbers and serialNumbers[0]):
1312
                raise TransactionServiceException(110, "No Serial Number supplied")
1313
            if serialNumbers:
1314
                lineitem.serial_number = serialNumbers[0]
6969 amar.kumar 1315
 
4283 anupam.sin 1316
 
2842 chandransh 1317
        order.status = OrderStatus.BILLED
1318
        order.statusDescription = "Order Billed"
1319
        order.billing_timestamp = datetime.datetime.now()
4285 rajveer 1320
        order.billed_by = billedBy
4435 mandeep.dh 1321
 
5436 mandeep.dh 1322
        # Letting the billing process fail in cases where we are unable to 
4435 mandeep.dh 1323
        # fill in transfer price
1324
        try:
5944 mandeep.dh 1325
            inventory_client = InventoryClient().get_client()
1326
            warehouse = inventory_client.getWarehouse(fulfilmentWarehouseId)
1327
            item_pricing = inventory_client.getItemPricing(item_id, warehouse.vendor.id)
5110 mandeep.dh 1328
            lineitem.transfer_price = item_pricing.transferPrice
6751 amar.kumar 1329
            lineitem.nlc = item_pricing.nlc
7330 amit.gupta 1330
            lineitem.vatRate = catalog_client.getVatPercentageForItem(lineitem.item_id, warehouse.stateId, lineitem.unit_price)
5110 mandeep.dh 1331
            order.vendorId = warehouse.vendor.id
4435 mandeep.dh 1332
        except InventoryServiceException as e:
1333
            print sys.exc_info()[0]
1334
            print e.message
5110 mandeep.dh 1335
            raise TransactionServiceException(110, 'Transfer price missing for itemId: ' + str(item_id) + ' and vendor: ' + str(warehouse.vendor.id))
4435 mandeep.dh 1336
 
5110 mandeep.dh 1337
        # For OUR warehouse, we need to scan out items for every billed order
1338
        if billingType == BillingType.OURS:
5530 mandeep.dh 1339
            for index, serialNumber in enumerate(serialNumbers):
5411 rajveer 1340
                try:
1341
                    warehouse_client = WarehouseClient().get_client()
5436 mandeep.dh 1342
                    # Fetching GOOD w/h corresponding to the virtual one here
5835 mandeep.dh 1343
                    if not warehouse.billingWarehouseId:
5950 mandeep.dh 1344
                        warehouse = inventory_client.getWarehouses(None, InventoryType.GOOD, warehouse.vendor.id, order.warehouse_id, 0)[0]
5436 mandeep.dh 1345
 
5411 rajveer 1346
                    if ItemType.SERIALIZED == item.type:
1347
                        inventoryItem = warehouse_client.getInventoryItem(serialNumber)
1348
                    else:
5661 mandeep.dh 1349
                        inventoryItem = warehouse_client.getNonSeralizedInventoryItem(itemNumbers[index], item_id, warehouse.id)
5411 rajveer 1350
 
1351
                    if (inventoryItem.itemId != item_id):
1352
                        catalog_client = CatalogClient().get_client()
1353
                        item = catalog_client.getItem(inventoryItem.itemId)
1354
                        scanItemString = " ".join([str(item.brand), str(item.modelName), str(item.modelNumber), str(item.color)])
1355
                        lineItemString = " ".join([str(lineitem.brand), str(lineitem.model_name), str(lineitem.model_number), str(lineitem.color)])
1356
                        raise TransactionServiceException(110, 'Trying to scan ' + scanItemString + ' instead of ' + lineItemString)
1357
 
1358
                    if ItemType.SERIALIZED == item.type:
5661 mandeep.dh 1359
                        inventoryItem = warehouse_client.scanSerializedItemForOrder(serialNumber, ScanType.SALE, orderId, warehouse.id, 1, order.warehouse_id)
5411 rajveer 1360
                    else:
5661 mandeep.dh 1361
                        inventoryItem = warehouse_client.scanForOrder(inventoryItem, ScanType.SALE, 1, order.id, warehouse.id, order.warehouse_id)
5411 rajveer 1362
 
1363
                    lineitem.transfer_price = inventoryItem.unitPrice
1364
                    order.vendorId = inventoryItem.supplierId
5636 amar.kumar 1365
                    catalog_client = CatalogClient().get_client()
5411 rajveer 1366
                except WarehouseServiceException as e:
1367
                    print sys.exc_info()[0]
1368
                    print 'Could not scan out orders due to: ' + e.message
1369
                    raise TransactionServiceException(110, e.message)
6763 amar.kumar 1370
        elif billingType == BillingType.OURS_EXTERNAL:
1371
            try:
6786 amar.kumar 1372
                if ItemType.SERIALIZED == item.type:
1373
                    serialNumber = serialNumbers[0]
1374
                else:
1375
                    serialNumber = ""
6763 amar.kumar 1376
                warehouse_client = WarehouseClient().get_client()
6768 amar.kumar 1377
                inventoryItem = warehouse_client.scanForOursExternalSale(lineitem.item_id, serialNumber, lineitem.item_number, invoice_number, order.fulfilmentWarehouseId, lineitem.transfer_price, order.id)
6763 amar.kumar 1378
                lineitem.transfer_price = inventoryItem.unitPrice
1379
                order.vendorId = inventoryItem.supplierId
1380
            except WarehouseServiceException as e:
1381
                print sys.exc_info()[0]
1382
                print 'Could not scan out orders due to: ' + e.message
1383
                raise TransactionServiceException(110, e.message)
5123 mandeep.dh 1384
        else:
1385
            if not warehouse.isAvailabilityMonitored:
5944 mandeep.dh 1386
                inventory_client = InventoryClient().get_client()
1387
                inventory_client.addInventory(item.id, warehouse.id, -1 * lineitem.quantity)
4365 mandeep.dh 1388
 
5110 mandeep.dh 1389
        __update_inventory_reservation(order)
5661 mandeep.dh 1390
        order.fulfilmentWarehouseId = warehouse.id
6969 amar.kumar 1391
        if billingType == BillingType.OURS or billingType == BillingType.OURS_EXTERNAL:
1392
            order.invoice_number = get_next_invoice_number(order.orderType)
4541 mandeep.dh 1393
        session.commit()
4283 anupam.sin 1394
        return True
1395
    else:
1396
        return False
1149 chandransh 1397
 
6751 amar.kumar 1398
def add_invoice_number(orderId, invoiceNumber, color, serialNumber, itemNumber):
4579 rajveer 1399
    order = Order.get_by(id=orderId)
1400
    if not order:
1401
        raise TransactionServiceException(101, "No order found for the given order id" + str(orderId))
1402
 
1403
    if order.status == OrderStatus.ACCEPTED:
1404
        order.invoice_number = invoiceNumber
4767 rajveer 1405
        if color:
6764 rajveer 1406
            billedOrdersColorMap[orderId] = color
6751 amar.kumar 1407
        if serialNumber:
6764 rajveer 1408
            order.lineitems[0].serial_number = serialNumber.strip() 
6751 amar.kumar 1409
        if itemNumber:
6764 rajveer 1410
            order.lineitems[0].item_number = itemNumber.strip()
4579 rajveer 1411
    session.commit()
1412
 
1220 chandransh 1413
def batch_orders(warehouseId):
1414
    if not warehouseId:
1415
        raise TransactionServiceException(101, "bad warehouse id")
1225 chandransh 1416
 
1417
    batchno_generator = BatchNoGenerator()
1418
    session.commit()
1220 chandransh 1419
    query = Order.query.filter_by(warehouse_id=warehouseId)
4592 mandeep.dh 1420
    query = query.filter(Order.status == OrderStatus.LOW_INV_PO_RAISED)
1220 chandransh 1421
    query = query.order_by(Order.created_timestamp)
1422
    pending_orders = query.all()
1225 chandransh 1423
 
1220 chandransh 1424
    serial_no = 1
1425
    for order in pending_orders:
1276 chandransh 1426
        order.batchNo = batchno_generator.id
1220 chandransh 1427
        order.serialNo = serial_no
1428
        serial_no += 1
1429
    session.commit() 
1430
    pending_orders = query.all()
1431
    return pending_orders
1432
 
1433
def order_outofstock(orderId):
1911 chandransh 1434
    '''
1435
    Mark order as out of stock
1436
    '''
1220 chandransh 1437
    order = get_order(orderId)
1438
    order.status = OrderStatus.INVENTORY_LOW
1439
    order.statusDescription = "Low Inventory"
1440
    order.outofstock_timestamp = datetime.datetime.now()
1441
    session.commit()
1442
    return True
1443
 
4789 rajveer 1444
def mark_orders_as_shipped_from_warehouse(warehouseId, providerId, cod, orderIds):
4410 rajveer 1445
    try:
1446
        current_timestamp = datetime.datetime.now()
5822 rajveer 1447
        orders = Order.query.filter(Order.id.in_(orderIds)).filter_by(warehouse_id = warehouseId, logistics_provider_id = providerId, status = OrderStatus.BILLED).all()
4410 rajveer 1448
        for order in orders:
5822 rajveer 1449
            order.status = OrderStatus.SHIPPED_FROM_WH
1450
            order.statusDescription = "Order shipped from warehouse"
1451
            order.shipping_timestamp = current_timestamp
1452
            try:
1453
                print "Trying to schedule alert"
1454
                monitoredEntity = MonitoredEntity();
1455
                monitoredEntity.entityType=EntityType.COURIER;
1456
                monitoredEntity.eventType=OrderStatus.SHIPPED_FROM_WH;
1457
                monitoredEntity.entityIdentifier="orderId = " + str(order.id);
1458
                adjustedDeliveryDays = adjust_delivery_time(datetime.datetime.now(), 1);
1459
                sec = datetime.datetime.now()
1460
                #Warn alert time is taken as 16 hrs
1461
                warn_time = (sec + timedelta(days=(adjustedDeliveryDays-1)) + timedelta(hours=16))
1462
                #Critical alert time is taken as 26 hrs                    
1463
                critical_time = (sec + timedelta(days=(adjustedDeliveryDays-1)) + timedelta(hours=26))
1464
                monitoredEntity.warnExpiryTime = int(warn_time.strftime("%s"))*1000
1465
                monitoredEntity.criticalExpiryTime = int(critical_time.strftime("%s"))*1000
1466
                monitoredEntity.description="warehouseId = " + str(warehouseId) + " providerId = " + str(providerId) + " orderId = "  + str(order.id);
1467
                alert_client = AlertClient().get_client()
1468
                alert_client.scheduleAlert(monitoredEntity)
1469
            except Exception as e:
1470
                print "Exception in scheduling alert in ShippedFromWarehouse method"
1471
                print e
759 chandransh 1472
        session.commit()
5832 rajveer 1473
 
4749 varun.gupt 1474
 
1475
        try:
5832 rajveer 1476
            for order in orders:
1477
                if order.pickupStoreId:
1478
                    send_mails_to_bdms(order)
1479
                else:
1480
                    enqueue_shipping_confirmation_email(order)
4749 varun.gupt 1481
        except Exception as e:
1482
            print e
5832 rajveer 1483
 
759 chandransh 1484
        return True
1485
    except:
1486
        return False
4410 rajveer 1487
 
5832 rajveer 1488
def send_mails_to_bdms(order):
5816 rajveer 1489
    logistics_client = LogisticsClient().get_client()
5832 rajveer 1490
    store = logistics_client.getPickupStore(order.pickupStoreId)
1491
    provider = logistics_client.getProvider(order.logistics_provider_id)
6029 rajveer 1492
    subject = source_name + " order " + str(order.id) +" shipped to store" 
5832 rajveer 1493
    raw_message = '''
1494
    Dear Sir,
5816 rajveer 1495
 
5832 rajveer 1496
    Order mentioned below is being shipped to your store. Customer will pick it from your store. 
1497
 
1498
    Store Id: %(store_id)s
1499
    Order Id: %(order_id)s 
1500
    Product: %(product)s
1501
    Delivery By: %(provider)s
5844 mandeep.dh 1502
    Payment Mode: %(payMode)s
1503
 
1504
    %(note)s
1505
 
5832 rajveer 1506
    Thanks and Regards
1507
    Sandeep Sachdeva
1508
    '''
1509
 
5844 mandeep.dh 1510
    payMode = 'Prepaid'
1511
    note = ''
1512
    if order.cod:
1513
        payMode = 'COD'
6318 rajveer 1514
        note = 'Note: Please collect Rs. ' + str(order.total_amount-order.gvAmount) + ' from customer'
5844 mandeep.dh 1515
 
5832 rajveer 1516
    message = dedent(raw_message) % { 'order_id' : str(order.id),
1517
                                     'store_id' : str(store.hotspotId),
1518
                                  'provider' : provider.name,
5844 mandeep.dh 1519
                                  'product' : str(order.lineitems[0]),
1520
                                  'payMode' : payMode,
1521
                                  'note'    : note
5832 rajveer 1522
                                  }
6643 rajveer 1523
    to_addresses = [store.email, store.bdmEmail, 'sandeep.sachdeva@shop2020.in', 'amit.sirohi@shop2020.in', 'manoj.kumar@shop2020.in']
5894 rajveer 1524
    cc = ['khushal.bhatia@spiceretail.co.in']
1525
    bcc = ['rajneesh.arora@spiceretail.co.in']
5966 rajveer 1526
    mail(mail_user, mail_password, to_addresses, subject, message, [], cc, bcc)
5816 rajveer 1527
 
5713 rajveer 1528
def mark_orders_as_returned_from_store(providerId, orderIds, awbs):
5676 rajveer 1529
    try:
1530
        current_timestamp = datetime.datetime.now()
5824 rajveer 1531
        orders = Order.query.filter(Order.id.in_(orderIds)).filter_by(logistics_provider_id = providerId, status = OrderStatus.RET_PICKUP_REQUEST_RAISED).all()
5676 rajveer 1532
        for order in orders:
6943 amar.kumar 1533
            order.status = OrderStatus.RTO_IN_TRANSIT
5824 rajveer 1534
            order.statusDescription = "Order returned from store"
1535
            order.doa_pickup_timestamp = current_timestamp
1536
            #order.airwaybill_no = awbs[orderIds.index(order.id)]
1537
            order.tracking_id = awbs[orderIds.index(order.id)]
5676 rajveer 1538
        session.commit()
1539
 
1540
        return True
1541
    except:
1542
        return False    
1543
 
1544
def set_order_attributes(orderId, attributes):
5871 rajveer 1545
    for attribute in attributes :
1546
        existingAttribute = Attribute.query.filter(Attribute.orderId == orderId).filter(Attribute.name == attribute.name).first()
1547
        if existingAttribute:
1548
            existingAttribute.value = attribute.value
1549
        else :                
1550
            attr = Attribute()
1551
            attr.orderId = orderId
1552
            attr.name = attribute.name
1553
            attr.value = attribute.value
5791 anupam.sin 1554
    session.commit()
5724 rajveer 1555
 
1113 chandransh 1556
def mark_orders_as_picked_up(provider_id, pickup_details):
1557
    for awb, pickup_timestamp in pickup_details.iteritems():
1135 chandransh 1558
        order = Order.query.filter_by(airwaybill_no=awb, logistics_provider_id = provider_id).first()
2684 chandransh 1559
        if order == None or order.status != OrderStatus.SHIPPED_FROM_WH:
2220 chandransh 1560
            #raise TransactionServiceException(102, "No order found for the awb: " + awb)
1561
            continue
1113 chandransh 1562
        order.status = OrderStatus.SHIPPED_TO_LOGST
1563
        order.statusDescription = "Order picked up by Courier Company"
1246 chandransh 1564
        order.pickup_timestamp = pickup_timestamp
5636 amar.kumar 1565
 
1566
        try:
1567
            monitoredEntity = MonitoredEntity();
1568
            monitoredEntity.entityType=EntityType.COURIER;
1569
            monitoredEntity.eventType=OrderStatus.SHIPPED_TO_LOGST
1570
            monitoredEntity.entityIdentifier="orderId = " + str(order.id);
5744 amar.kumar 1571
            adjustedDeliveryDays = adjust_delivery_time(datetime.datetime.now(), 1);
1572
            sec = datetime.datetime.now()
1573
            #Warn alert time is taken as 16 hrs
5821 amit.gupta 1574
            warn_time = (sec + timedelta(days=(adjustedDeliveryDays-1)) + timedelta(hours=15))
5744 amar.kumar 1575
            #Critical alert time is taken as 26 hrs                    
5821 amit.gupta 1576
            critical_time = (sec + timedelta(days=(adjustedDeliveryDays-1)) + timedelta(hours=20))
5744 amar.kumar 1577
            monitoredEntity.warnExpiryTime = int(warn_time.strftime("%s"))*1000
1578
            monitoredEntity.criticalExpiryTime = int(critical_time.strftime("%s"))*1000
5819 amit.gupta 1579
            monitoredEntity.description="providerId = " + str(provider_id)
5636 amar.kumar 1580
            alert_client = AlertClient().get_client()
1581
            alert_client.updateMonitoredObject(monitoredEntity)
1582
        except Exception as e:
5801 amar.kumar 1583
            print "Exception in updating alert in MarkOrdersAsPickedUp method"
5636 amar.kumar 1584
            print e
1113 chandransh 1585
    session.commit()
1217 chandransh 1586
 
4910 phani.kuma 1587
def get_orders_not_picked_up(provider_id):
1132 chandransh 1588
    current_time = datetime.datetime.now()
1589
    to_datetime = datetime.datetime(current_time.year, current_time.month, current_time.day)
4741 phani.kuma 1590
    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()
1113 chandransh 1591
    return orders_not_picked_up
1592
 
1132 chandransh 1593
def mark_orders_as_delivered(provider_id, delivered_orders):
1594
    for awb, detail in delivered_orders.iteritems():
1135 chandransh 1595
        order = Order.query.filter_by(airwaybill_no=awb, logistics_provider_id = provider_id).first()
4910 phani.kuma 1596
        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]:
1911 chandransh 1597
            continue
6561 amit.gupta 1598
        timestamp, receiver = detail.split('|')
1599
        order.delivery_timestamp = datetime.datetime.strptime(timestamp, "%Y-%m-%d %H:%M:%S")
1600
        if order.first_dlvyatmp_timestamp is None:
1601
            order.first_dlvyatmp_timestamp = order.delivery_timestamp
1602
        order.receiver = receiver
5555 rajveer 1603
        if order.pickupStoreId:
1604
            order.status = OrderStatus.DELIVERED_AT_STORE
1605
            order.statusDescription = "Order delivered At Store"
5762 amar.kumar 1606
            try:
1607
                monitoredEntity = MonitoredEntity();
1608
                monitoredEntity.entityType=EntityType.COURIER;
1609
                monitoredEntity.eventType=OrderStatus.RECEIVED_AT_STORE;
1610
                monitoredEntity.entityIdentifier="orderId = " + str(order.id);
1611
                #adjustedDeliveryDays = adjust_delivery_time(datetime.datetime.now(), 1);
1612
                sec = datetime.datetime.now()
1613
                #Critical alert time is taken as 26 hrs                    
1614
                critical_time = (sec + timedelta(hours=4))
1615
                monitoredEntity.criticalExpiryTime = int(critical_time.strftime("%s"))*1000
1616
                monitoredEntity.description="deliveryTimeAtStore = " + str(order.delivery_timestamp) + " orderId = "  + str(order.id);
1617
                alert_client = AlertClient().get_client()
1618
                alert_client.updateMonitoredObject(monitoredEntity)
1619
            except Exception as e:
1620
                print e
5555 rajveer 1621
        else:
1622
            order.status = OrderStatus.DELIVERY_SUCCESS
1623
            order.statusDescription = "Order delivered"
5762 amar.kumar 1624
            update_trust_level(order)
6903 anupam.sin 1625
            if order.insuranceDetails:
6906 rajveer 1626
                try:
1627
                    update_insurance_details(order)
1628
                except:
1629
                    print "Error generating insurance file for order " + str(order.id)
1630
                    session.rollback()
1631
                    return
1632
 
6745 anupam.sin 1633
            if enqueue_delivery_success_mail(order) :
1634
                session.commit()
1635
            else :
1636
                session.rollback()
5762 amar.kumar 1637
            try:
1638
                alert_client = AlertClient().get_client()
1639
                alert_client.endMonitoringEntity(EntityType.COURIER, "orderId = " + str(order.id))
1640
            except Exception as e:
5801 amar.kumar 1641
                print "Exception in scheduling alert in ShippedFromWarehouse method"
5762 amar.kumar 1642
                print e
5636 amar.kumar 1643
 
6906 rajveer 1644
def update_insurance_details(order):
1645
    order.insuranceDetails[0].startDate = order.delivery_timestamp
1646
    order.insuranceDetails[0].expiryDate = order.delivery_timestamp + timedelta(days = 365)
6947 rajveer 1647
    filename = "/tmp/" + str(order.id) + "-insurance-policy.pdf"
6906 rajveer 1648
    __generate_policy_doc(order, filename)
1649
    file = open(filename, "rb")
1650
    pdfFile = file.read()
1651
    doc = DocumentStore()
1652
    doc.docType = 1
1653
    doc.docSource = order.id
1654
    doc.document = pdfFile
1132 chandransh 1655
 
4712 rajveer 1656
def mark_order_as_delivered(orderId, deliveryTimestamp, receiver):
1657
    order = Order.get_by(id=orderId)
5555 rajveer 1658
    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]:
4712 rajveer 1659
        raise TransactionServiceException(101, "Either wrond order id or invalid state " + str(orderId))
5402 rajveer 1660
 
1661
    # Provider is 4 is for self pickup and hardcoded. We should figure out a way to not to hard code.   
1662
    if order.status == OrderStatus.BILLED and order.logistics_provider_id != 4:
5807 rajveer 1663
        raise TransactionServiceException(101, "Order is not marked for self pickup: " + str(orderId))
5402 rajveer 1664
 
5555 rajveer 1665
    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]:
6632 amit.gupta 1666
        order.delivery_timestamp = deliveryTimestamp
6631 amit.gupta 1667
        if order.first_dlvyatmp_timestamp is None:
6632 amit.gupta 1668
            order.first_dlvyatmp_timestamp = deliveryTimestamp
4712 rajveer 1669
        order.receiver = receiver
1670
    order.status = OrderStatus.DELIVERY_SUCCESS
1671
    order.statusDescription = "Order delivered"
1672
    update_trust_level(order)
6903 anupam.sin 1673
    if order.insuranceDetails:
6906 rajveer 1674
        try:
1675
            update_insurance_details(order)
1676
        except:
1677
            print "Error generating insurance file for order " + str(order.id)
1678
            session.rollback()
1679
            return
4712 rajveer 1680
    session.commit()
5713 rajveer 1681
 
5812 rajveer 1682
    if order.pickupStoreId and order.cod:
5806 rajveer 1683
        __push_collection_to_hotspot(order, "SALE")
1684
 
5966 rajveer 1685
    enqueue_delivery_success_mail(order)
5713 rajveer 1686
#    if order.pickupStoreId:
1687
#        payment_client = PaymentClient().get_client()
1688
#        payment_client.createRefund(order.id, order.transaction.id, order.total_amount)
1689
#        payment_client = PaymentClient().get_client()
1690
#        payment_client.partiallyCapturePayment(order.transaction.id, order.total_amount, xferBy, xferTxnId, now())
1691
#        order.cod_reconciliation_timestamp = datetime.datetime.now()
1692
#        session.commit()
1693
 
5636 amar.kumar 1694
    try:
1695
        alert_client = AlertClient().get_client()
5744 amar.kumar 1696
        alert_client.endMonitoringEntity(EntityType.COURIER, "orderId = " + str(order.id))
5636 amar.kumar 1697
    except Exception as e:
5801 amar.kumar 1698
        print "Exception in ending alert in MarkOrderAsDelivered method"
5636 amar.kumar 1699
        print e
1700
 
4712 rajveer 1701
 
5555 rajveer 1702
def mark_order_as_received_at_store(orderId, deliveryTimestamp):
1703
    order = Order.get_by(id=orderId)
1704
    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]:
1705
        order.status = OrderStatus.RECEIVED_AT_STORE
1706
        order.statusDescription = "Order received at store"
1707
        order.delivery_timestamp = deliveryTimestamp
1708
    session.commit()
5713 rajveer 1709
    try:
5762 amar.kumar 1710
        alert_client = AlertClient().get_client()
1711
        alert_client.endMonitoringEntity(EntityType.COURIER, "orderId = " + str(order.id))
1712
    except Exception as e:
1713
        print e
1714
 
1715
    try:
5713 rajveer 1716
        enqueue_received_at_store_email(order)
1717
    except Exception as e:
1718
        print e
1719
 
1720
 
5555 rajveer 1721
 
4910 phani.kuma 1722
def mark_orders_as_rto(provider_id, returned_orders):
1135 chandransh 1723
    for awb, detail in returned_orders.iteritems():
1724
        order = Order.query.filter_by(airwaybill_no=awb, logistics_provider_id = provider_id).first()
5713 rajveer 1725
        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]:
2684 chandransh 1726
            continue
1727
            #raise TransactionServiceException(103, "No order found for the awb:" + awb)
4484 rajveer 1728
        order.status = OrderStatus.RTO_IN_TRANSIT
1135 chandransh 1729
        order.delivery_timestamp, reason = detail.split('|')
1730
        order.statusDescription = "Order Returned to Origin:" + reason
3578 mandeep.dh 1731
        update_trust_level(order)
1911 chandransh 1732
    session.commit()
5636 amar.kumar 1733
    try:
1734
        alert_client = AlertClient().get_client()
5801 amar.kumar 1735
        alert_client.endMonitoringEntity(EntityType.COURIER, "orderId = " + str(order.id))
5636 amar.kumar 1736
    except Exception as e:
5801 amar.kumar 1737
        print "Exception in ending alert in MarkOrderAsRTO method"
5636 amar.kumar 1738
        print e
1135 chandransh 1739
 
4910 phani.kuma 1740
def get_rto_orders(provider_id):
1741
    current_time = datetime.datetime.now()
1742
    to_datetime = datetime.datetime(current_time.year, current_time.month, current_time.day)
1743
    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()
1744
    return rto_orders
1745
 
5555 rajveer 1746
def get_receive_pending_orders(storeId):
1747
    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()
1748
 
1749
def get_received_at_store_orders(storeId):
5676 rajveer 1750
    return Order.query.filter_by(pickupStoreId = storeId).filter(Order.status.in_((OrderStatus.RECEIVED_AT_STORE, OrderStatus.RET_PICKUP_REQUEST_RAISED))).all()
5555 rajveer 1751
 
5713 rajveer 1752
def get_orders_collection_at_store(storeId, fromDate, toDate, onlyCod):
1753
    query = Order.query.filter(Order.status == OrderStatus.DELIVERY_SUCCESS)
1754
    if storeId:
1755
        query = query.filter_by(pickupStoreId = storeId)
5720 rajveer 1756
    else:
1757
        query = query.filter(Order.pickupStoreId != 0)
5713 rajveer 1758
    if onlyCod:
1759
        query = query.filter_by(cod = onlyCod)
1760
    if fromDate:
1761
        query = query.filter(Order.delivery_timestamp >= fromDate)
1762
    if toDate:
1763
        query = query.filter(Order.delivery_timestamp <= toDate)
1764
    return query.all()
1765
 
1246 chandransh 1766
def update_non_delivery_reason(provider_id, undelivered_orders):
1767
    for awb, reason in undelivered_orders.iteritems():
1768
        order = Order.query.filter_by(airwaybill_no=awb, logistics_provider_id = provider_id).first()
4920 phani.kuma 1769
        if order == None or order.status == OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE:
2684 chandransh 1770
            continue
1771
            #raise TransactionServiceException(103, "No order found for the awb:" + awb)
1246 chandransh 1772
        order.statusDescription = reason
1773
    session.commit()
4910 phani.kuma 1774
 
1775
def get_non_delivered_orders_by_courier(provider_id):
4581 phani.kuma 1776
    current_time = datetime.datetime.now()
1777
    today_datetime = datetime.datetime(current_time.year, current_time.month, current_time.day)
1778
    upto_datetime = today_datetime - datetime.timedelta(4)
4910 phani.kuma 1779
    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()
4581 phani.kuma 1780
    return orders_not_delivered
1246 chandransh 1781
 
4910 phani.kuma 1782
def mark_orders_as_local_connected(provider_id, local_connected_orders):
1783
    for awb, timestamp in local_connected_orders.iteritems():
1784
        order = Order.query.filter_by(airwaybill_no=awb, logistics_provider_id = provider_id).first()
1785
        if order == None or order.status not in [OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST]:
1786
            #raise TransactionServiceException(102, "No order found for the awb: " + awb)
1787
            continue
1788
        order.status = OrderStatus.SHIPPED_TO_DESTINATION_CITY
1789
        order.statusDescription = "Left Out of Origin City"
5636 amar.kumar 1790
        current_time = datetime.datetime.now()
1791
        order.local_connected_timestamp = datetime.datetime(current_time.year, current_time.month, current_time.day)
1792
        try:
1793
            monitoredEntity = MonitoredEntity();
1794
            monitoredEntity.entityType=EntityType.COURIER;
1795
            monitoredEntity.eventType=OrderStatus.SHIPPED_TO_DESTINATION_CITY
1796
            monitoredEntity.entityIdentifier="orderId = " + str(order.id);
5744 amar.kumar 1797
            #Warn alert time is taken as 23 hrs less than promised delivery time
5821 amit.gupta 1798
            warn_time = (order.expected_delivery_time-timedelta(hours = 15))
5744 amar.kumar 1799
            #Critical alert time is taken as 13 hrs less than promised delivery time                    
5821 amit.gupta 1800
            critical_time = (order.expected_delivery_time-timedelta(hours = 10))
5801 amar.kumar 1801
            monitoredEntity.warnExpiryTime = int(warn_time.strftime("%s"))*1000
1802
            monitoredEntity.criticalExpiryTime = int(critical_time.strftime("%s"))*1000
5636 amar.kumar 1803
            monitoredEntity.description="providerId = " + str(provider_id) + " destination city " + order.customer_city 
1804
            alert_client = AlertClient().get_client()
1805
            alert_client.updateMonitoredObject(monitoredEntity)
1806
        except Exception as e:
5801 amar.kumar 1807
            print "Exception in updating alert in MarkOrderAsLocalConnected method"
5636 amar.kumar 1808
            print e
1809
        session.commit()
4910 phani.kuma 1810
 
1811
def get_orders_not_local_connected(provider_id):
1812
    current_time = datetime.datetime.now()
1813
    to_datetime = datetime.datetime(current_time.year, current_time.month, current_time.day)
1814
    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()
1815
    return orders_pending_local_connection
1816
 
1817
def mark_orders_as_destinationCityReached(provider_id, destination_city_reached_orders):
1818
    for awb, timestamp in destination_city_reached_orders.iteritems():
1819
        order = Order.query.filter_by(airwaybill_no=awb, logistics_provider_id = provider_id).first()
1820
        if order == None or order.status not in [OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY]:
1821
            continue
1822
            #raise TransactionServiceException(103, "No order found for the awb:" + awb)
1823
        order.status = OrderStatus.REACHED_DESTINATION_CITY
1824
        order.statusDescription = "Reached Destination City"
1825
        order.reached_destination_timestamp = timestamp
5636 amar.kumar 1826
        try:
1827
            monitoredEntity = MonitoredEntity();
1828
            monitoredEntity.entityType=EntityType.COURIER;
1829
            monitoredEntity.eventType=OrderStatus.REACHED_DESTINATION_CITY
1830
            monitoredEntity.entityIdentifier="orderId = " + str(order.id);
5764 amar.kumar 1831
            warn_time = (order.expected_delivery_time)
5801 amar.kumar 1832
            critical_time = (order.expected_delivery_time + timedelta(hours=12))
1833
            monitoredEntity.warnExpiryTime = int(warn_time.strftime("%s"))*1000
1834
            monitoredEntity.criticalExpiryTime = int(critical_time.strftime("%s"))*1000
5636 amar.kumar 1835
            monitoredEntity.description="providerId = " + str(provider_id) + " destination city " + order.customer_city 
1836
            alert_client = AlertClient().get_client()
1837
            alert_client.updateMonitoredObject(monitoredEntity)
1838
        except Exception as e:
5801 amar.kumar 1839
            print "Exception in updating alert in MarkOrderAsDestCityReached method"
5636 amar.kumar 1840
            print e
4910 phani.kuma 1841
    session.commit()
1842
 
1843
def mark_orders_as_firstDeliveryAttempted(provider_id, first_atdl_orders):
1844
    for awb, detail in first_atdl_orders.iteritems():
1845
        order = Order.query.filter_by(airwaybill_no=awb, logistics_provider_id = provider_id).first()
1846
        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]:
1847
            continue
1848
            #raise TransactionServiceException(103, "No order found for the awb:" + awb)
1849
        order.status = OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE
1850
        order.first_dlvyatmp_timestamp, reason = detail.split('|')
1851
        order.statusDescription = reason
5636 amar.kumar 1852
        try:
1853
            monitoredEntity = MonitoredEntity();
1854
            monitoredEntity.entityType=EntityType.COURIER;
1855
            monitoredEntity.eventType=OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE
1856
            monitoredEntity.entityIdentifier="orderId = " + str(order.id);
5744 amar.kumar 1857
            adjustedDeliveryDaysfor1day = adjust_delivery_time(datetime.datetime.now(), 1);
1858
            adjustedDeliveryDaysfor2days = adjust_delivery_time(datetime.datetime.now(), 2);
1859
            sec = datetime.datetime.now()
1860
            #Warn alert time is taken as 16 hrs
1861
            warn_time = (sec + timedelta(days=(adjustedDeliveryDaysfor1day-1)) + timedelta(hours=24))
1862
            #Critical alert time is taken as 26 hrs                    
1863
            critical_time = (sec + timedelta(days=(adjustedDeliveryDaysfor2days-1)) + timedelta(hours=36))
1864
            monitoredEntity.warnExpiryTime = int(warn_time.strftime("%s"))*1000
1865
            monitoredEntity.criticalExpiryTime = int(critical_time.strftime("%s"))*1000
5636 amar.kumar 1866
            monitoredEntity.description="providerId = " + str(provider_id) + " first attempt timestamp" + order.first_dlvyatmp_timestamp
1867
            alert_client = AlertClient().get_client()
1868
            alert_client.updateMonitoredObject(monitoredEntity)
1869
        except Exception as e:
5801 amar.kumar 1870
            print "Exception in updating alert in MarkOrdersAsFirstDeliveryAttempted method"
5636 amar.kumar 1871
            print e
4910 phani.kuma 1872
    session.commit()
1873
 
4783 phani.kuma 1874
def get_orders_not_met_expected_delivery_date():
1875
    current_time = datetime.datetime.now()
1876
    today_datetime = datetime.datetime(current_time.year, current_time.month, current_time.day)
4910 phani.kuma 1877
    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()
4783 phani.kuma 1878
    return orders_not_delivered
1879
 
4444 rajveer 1880
def get_alerts(type, warehouseId, status, timestamp):
1881
    query = Alert.query.filter(Alert.warehouseId == warehouseId)
1882
    if type != -1 :
1883
        query = query.filter(Alert.type == type)
1884
    if status != -1 :
1885
        query = query.filter(Alert.status == status)
4394 rajveer 1886
    if timestamp:
1887
        query = query.filter(Alert.timestamp >= to_py_date(timestamp))
4412 rajveer 1888
    query = query.order_by(desc(Alert.timestamp))
483 rajveer 1889
    return query.all()
1890
 
4447 rajveer 1891
def add_alert(type, warehouseId, description):
4394 rajveer 1892
    alert = Alert()
1893
    alert.type = type
1894
    alert.status = 1
1895
    alert.description = description
1896
    alert.timestamp = datetime.datetime.now()
4447 rajveer 1897
    alert.warehouseId = warehouseId
4444 rajveer 1898
    session.commit()
766 rajveer 1899
 
4444 rajveer 1900
def mark_alerts_as_seen(warehouseId):
1901
    query = Alert.query.filter(Alert.warehouseId == warehouseId).filter(Alert.status == 1)
1902
    alerts = query.all()
1903
    for alert in alerts:
1904
        alert.status = 0    
1905
    session.commit()
1906
 
1596 ankur.sing 1907
def get_valid_order_count():
2851 chandransh 1908
    '''
1909
    Returns the number of orders which we processed. The reshipped orders are not
1910
    counted since there'll always be a new compensating order present.
1911
    '''
4682 rajveer 1912
    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()
1596 ankur.sing 1913
 
1627 ankur.sing 1914
def get_cust_count_with_successful_txn():
2851 chandransh 1915
    '''
1916
    Returns the number of distinct customers who have done successful transactions.
1917
    It uses the sqlalchemy func module to construct an efficient query.
1918
    '''
1919
    return session.query(func.count(distinct(Order.customer_id))).filter(Order.status >= OrderStatus.SUBMITTED_FOR_PROCESSING).scalar()
1627 ankur.sing 1920
 
1730 ankur.sing 1921
def get_valid_orders_amount_range():
2851 chandransh 1922
    '''
1923
    Returns a list containing the minimum and maximum amount across all
1924
    orders placed with us. No need to consider reshippped orders for min/max
1925
    amount of orders.
1926
    '''
1927
    return session.query(func.min(Order.total_amount), func.max(Order.total_amount)).filter(Order.status >= OrderStatus.SUBMITTED_FOR_PROCESSING).one()
1627 ankur.sing 1928
 
5874 rajveer 1929
def get_valid_orders(limit, onlyStore):
2851 chandransh 1930
    '''
1931
    Returns the last limit number of valid orders placed with us. Ignored the
1932
    limit if it's passed as 0. Raises an excpetion if the supplied limit is 
1933
    less than 0. 
1934
    '''
1935
    if limit < 0:
1936
        raise TransactionServiceException(101, "Invalid argument limit " + limit)
4662 rajveer 1937
    query = Order.query.filter(Order.status >= OrderStatus.COD_VERIFICATION_PENDING)
5874 rajveer 1938
    if onlyStore:
1939
        query = query.filter(Order.pickupStoreId != 0)
1886 ankur.sing 1940
    query = query.order_by(desc(Order.created_timestamp))
2851 chandransh 1941
    if limit != 0:
1886 ankur.sing 1942
        query = query.limit(limit)
1943
    return query.all()
1944
 
5527 anupam.sin 1945
def get_next_invoice_number(orderType):
1946
    if OrderType.B2Cbulk == orderType:
1947
        orderType = OrderType.B2C
1948
    entity_id = InvoiceIDGenerator.query.filter(InvoiceIDGenerator.orderType == orderType).with_lockmode("update").one()
2783 chandransh 1949
    invoice_number = entity_id.id + 1
1950
    entity_id.id = invoice_number
1951
    return invoice_number
1952
 
2536 chandransh 1953
def toggle_doa_flag(order_id):
1954
    order = get_order(order_id)
1955
    if(order.doaFlag):
1956
        order.doaFlag = False
1957
    else:
1958
        order.doaFlag = True
1959
    session.commit()
1960
    return order.doaFlag
1961
 
4454 rajveer 1962
def mark_order_doa_request_received(orderId):
1963
    order = get_order(orderId)
1964
    if order.status != OrderStatus.DELIVERY_SUCCESS:
1965
        return False
1966
    order.status = OrderStatus.DOA_REQUEST_RECEIVED
4459 rajveer 1967
    order.statusDescription = "DOA Request Received"
4454 rajveer 1968
    session.commit()
1969
    return True
1970
 
1971
def mark_order_doa_request_authorized(orderId, isAuthorized):
1972
    order = get_order(orderId)
1973
    if order.status != OrderStatus.DOA_REQUEST_RECEIVED:
1974
        return False
1975
    if isAuthorized:
1976
        order.status = OrderStatus.DOA_REQUEST_AUTHORIZED
4459 rajveer 1977
        order.statusDescription = "DOA Request Authorized"
4454 rajveer 1978
    else:
1979
        order.status = OrderStatus.DELIVERY_SUCCESS
4459 rajveer 1980
        order.statusDescription = "Order delivered"
4454 rajveer 1981
    session.commit()
1982
    return True
1983
 
4488 rajveer 1984
def mark_order_return_request_received(orderId):
1985
    order = get_order(orderId)
1986
    if order.status != OrderStatus.DELIVERY_SUCCESS:
1987
        return False
1988
    order.status = OrderStatus.RET_REQUEST_RECEIVED
1989
    order.statusDescription = "Return Request Received"
1990
    session.commit()
1991
    return True
1992
 
1993
def mark_order_return_request_authorized(orderId, isAuthorized):
1994
    order = get_order(orderId)
1995
    if order.status != OrderStatus.RET_REQUEST_RECEIVED:
1996
        return False
1997
    if isAuthorized:
1998
        order.status = OrderStatus.RET_REQUEST_AUTHORIZED
1999
        order.statusDescription = "Return Request Authorized"
2000
    else:
2001
        order.status = OrderStatus.DELIVERY_SUCCESS
2002
        order.statusDescription = "Order delivered"
2003
    session.commit()
2004
    return True
2005
 
4579 rajveer 2006
def request_pickup_number(order_id, providerId):
2536 chandransh 2007
    order = get_order(order_id)
4495 rajveer 2008
    if order.status != OrderStatus.DELIVERY_SUCCESS and order.status != OrderStatus.DOA_REQUEST_AUTHORIZED and order.status != OrderStatus.RET_REQUEST_AUTHORIZED:
2536 chandransh 2009
        return False
2010
 
4227 rajveer 2011
    subject = "Pickup request from " + order.customer_city
2536 chandransh 2012
    try:
5944 mandeep.dh 2013
        inventory_client = InventoryClient().get_client()
2014
        warehouse = inventory_client.getWarehouse(order.warehouse_id)
2536 chandransh 2015
 
2016
        logistics_client = LogisticsClient().get_client()
4579 rajveer 2017
        provider = logistics_client.getProvider(providerId)
3051 chandransh 2018
        to_addr = provider.details[DeliveryType.PREPAID].email
2536 chandransh 2019
        raw_message = '''
2020
        Dear Sir/Madam,
2021
 
2559 chandransh 2022
        Kindly arrange a pickup today from %(customer_city)s. Pickup and delivery addresses are mentioned below.
2536 chandransh 2023
 
6663 rajveer 2024
        Order Id: %(order_id)s
2536 chandransh 2025
        Pickup CODE: %(provider_code)s
2026
        Total Weight: %(order_weight)s kg
2027
 
2559 chandransh 2028
        Pickup Address:
2536 chandransh 2029
 
2030
        %(customer_address)s
2031
 
2032
        Delivery Address:
2033
 
2034
        %(warehouse_executive)s
2035
        %(warehouse_address)s
2036
        PIN %(warehouse_pin)s
2037
 
2038
        Thanks and Regards
4227 rajveer 2039
        Sandeep Sachdeva
2536 chandransh 2040
        '''
4579 rajveer 2041
 
2042
        if warehouse.id == 7:
7181 rajveer 2043
            executive = 'Shiv Kumar'
4579 rajveer 2044
        else:
4966 phani.kuma 2045
            executive = 'Dinesh Kumar'
4579 rajveer 2046
 
2559 chandransh 2047
        message = dedent(raw_message) % { 'customer_city' : order.customer_city,
3051 chandransh 2048
                                          'provider_code' : provider.details[DeliveryType.PREPAID].accountNo,
6663 rajveer 2049
                                          'order_id' : str(order_id),
2536 chandransh 2050
                                          'order_weight' : str(order.total_weight),
2051
                                          'customer_address' : __get_order_address(order),
4579 rajveer 2052
                                          'warehouse_executive' : executive,
2536 chandransh 2053
                                          'warehouse_address' : warehouse.location,
4966 phani.kuma 2054
                                          'warehouse_pin' : warehouse.pincode}
6645 anupam.sin 2055
        to_addresses = [to_addr,'amit.sirohi@shop2020.in', 'shrawan.choudhary@shop2020.in', 'ritesh.chauhan@shop2020.in']
4966 phani.kuma 2056
 
5966 rajveer 2057
        mail(mail_user, mail_password, to_addresses, subject, message)
4495 rajveer 2058
        if order.status == OrderStatus.RET_REQUEST_AUTHORIZED:
2059
            order.status = OrderStatus.RET_PICKUP_REQUEST_RAISED
2060
            order.statusDescription = "Pick up requested for RETURN"
2061
        else:
2062
            order.status = OrderStatus.DOA_PICKUP_REQUEST_RAISED
2063
            order.statusDescription = "Pick up requested for DOA"
4815 phani.kuma 2064
        order.doa_logistics_provider_id = providerId
2536 chandransh 2065
        session.commit()
2066
        return True
2067
    except Exception as e:
2068
        print sys.exc_info()[0]
2069
        return False
2070
 
4602 rajveer 2071
def authorize_pickup(order_id, pickup_number, providerId):
2536 chandransh 2072
    order = get_order(order_id)
4495 rajveer 2073
    if order.status not in [OrderStatus.DOA_PICKUP_REQUEST_RAISED, OrderStatus.RET_PICKUP_REQUEST_RAISED]:
2536 chandransh 2074
        return False
4815 phani.kuma 2075
    if order.doa_logistics_provider_id is not None:
2076
        providerId = order.doa_logistics_provider_id    #previously we are not storing this so data is taken from omdashboarduser
2536 chandransh 2077
    subject = 'Pickup details'
2078
    filename = "/tmp/" +  str(order.id) +".pdf" 
2079
    try:
5944 mandeep.dh 2080
        inventory_client = InventoryClient().get_client()
2081
        warehouse = inventory_client.getWarehouse(order.warehouse_id)
2536 chandransh 2082
 
2083
        logistics_client = LogisticsClient().get_client()
4602 rajveer 2084
        provider = logistics_client.getProvider(providerId)
2536 chandransh 2085
        provider_name = provider.name
2086
 
2087
        to_addr = order.customer_email
2088
        today = date.today().strftime("%d-%B-%Y (%A)")
2089
 
2090
        raw_message = '''
2091
        Dear Mr. %(customer_name)s,
2092
 
4815 phani.kuma 2093
        In reference to the return of order ID %(order_id)d, ''' + __generate_mail_body_for_authorize_pickup(order)
2094
        raw_message = raw_message + '''
2536 chandransh 2095
        Take a printout of the attachment in this mail which contains the delivery address and paste it on the packed parcel.
2096
        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. Kindly keep the parcel ready.
2097
 
2098
        Pickup will happen from the below mentioned address:-
2099
 
2100
        %(customer_address)s
2101
 
2102
        Do let us know in case of any concerns
2103
 
2104
        Thanks & Regards
6029 rajveer 2105
        %(source_name)s Team
2536 chandransh 2106
        '''
2107
        message = dedent(raw_message) % {'customer_name' : order.customer_name,
2108
                                         'order_id' : order_id,
2109
                                         'provider_name' : provider_name,
2110
                                         'date': today,
2111
                                         'pickup_request_no' : pickup_number,
6029 rajveer 2112
                                         'customer_address' : __get_order_address(order),
2113
                                         'source_name' : source_name}
2536 chandransh 2114
        print message
2115
        __generate_return_advice(order, warehouse, provider, filename)
5966 rajveer 2116
        mail(help_user, help_password, [to_addr], subject, message, [get_attachment_part(filename)])
2536 chandransh 2117
        order.pickupRequestNo = pickup_number
4495 rajveer 2118
        if order.status == OrderStatus.RET_PICKUP_REQUEST_RAISED:
2119
            order.status = OrderStatus.RET_PICKUP_CONFIRMED
2120
            order.statusDescription = "RETURN pick up confirmed"
2121
        else:
2122
            order.status = OrderStatus.DOA_PICKUP_CONFIRMED
2123
            order.statusDescription = "DOA pick up confirmed"
2764 chandransh 2124
        order.doa_auth_timestamp = datetime.datetime.now()
2536 chandransh 2125
        session.commit()
2126
        return True
2127
    except Exception as e:
4234 rajveer 2128
        print sys.exc_info()
4506 phani.kuma 2129
        traceback.print_tb(sys.exc_info()[2])
2536 chandransh 2130
        return False
2131
    finally:
2132
        if os.path.exists(filename):
2133
            os.remove(filename)
2134
 
4815 phani.kuma 2135
def __generate_mail_body_for_authorize_pickup(order):
2136
    brand_msgbody_map = {'Nokia' : 'we request you to kindly pack the box properly with bubble wrap, and send it along with the all original accessories, original handset and the invoice.',
2137
                         'Micromax' : 'we request you to kindly pack the box properly with bubble wrap, and send it along with the all original accessories, original handset and the invoice.',
2138
                         'Karbonn' : 'we request you to kindly pack the box properly with bubble wrap, and send it along with the all original accessories, original handset and the invoice.',
2139
                         'Sony Ericsson' : 'we request you to kindly pack the original DOA certificate and the invoice.',
2140
                         'Others Handsets' : 'we request you to kindly pack the box properly with bubble wrap, and send it along with the original "DOA" certificate and the invoice. Please paste the original DOA on the sealed box. Kindly ensure that the product is properly sealed. If we receive open sealed products, we will not be able to accept.',
2141
                         'Handsets Return' : 'we request you to kindly pack the box properly with bubble wrap, and send it along with the all original accessories, original handset and the invoice.',
2142
                         'Accessories' : 'we request you to kindly pack the box properly with bubble wrap, and send it along with the original product and the invoice.'}
2143
    categories = ["Handsets", "Tablets", "Laptops"]
2144
    lineitem = order.lineitems[0]
2145
    brand = lineitem.brand
2146
    productGroup = lineitem.productGroup
2147
    searchkey = None
2148
    if productGroup not in categories:
2149
        searchkey = 'Accessories'
2150
    elif order.status == OrderStatus.RET_PICKUP_REQUEST_RAISED:
2151
        searchkey = 'Handsets Return'
2152
    elif brand == 'Nokia':
2153
        searchkey = 'Nokia'
2154
    elif brand == 'Micromax':
2155
        searchkey = 'Micromax'
2156
    elif brand == 'Karbonn':
2157
        searchkey = 'Karbonn'
2158
    elif brand == 'Sony Ericsson':
2159
        searchkey = 'Sony Ericsson'
2160
    else:
2161
        searchkey = 'Others Handsets'
2162
    return brand_msgbody_map.get(searchkey)
2163
 
2764 chandransh 2164
def mark_doas_as_picked_up(provider_id, pickup_details):
2165
    for pickupNo, doa_pickup_timestamp in pickup_details.iteritems():
4815 phani.kuma 2166
        order = Order.query.filter_by(pickupRequestNo=pickupNo, doa_logistics_provider_id = provider_id).first()
4452 rajveer 2167
        if order == None or order.status != OrderStatus.DOA_PICKUP_CONFIRMED:
2764 chandransh 2168
            #raise TransactionServiceException(102, "No order found for the awb: " + awb)
2169
            continue
2170
        order.status = OrderStatus.DOA_RETURN_IN_TRANSIT
2171
        order.statusDescription = "DOA picked up by Courier Company"
2172
        order.doa_pickup_timestamp = doa_pickup_timestamp
2173
    session.commit()
2174
 
4910 phani.kuma 2175
def get_doas_not_picked_up(provider_id):
2764 chandransh 2176
    current_time = datetime.datetime.now()
2177
    to_datetime = datetime.datetime(current_time.year, current_time.month, current_time.day)
4815 phani.kuma 2178
    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()
2764 chandransh 2179
    return orders_not_picked_up
2180
 
4741 phani.kuma 2181
def mark_return_orders_as_picked_up(provider_id, pickup_details):
2182
    for pickupNo, return_order_pickup_timestamp in pickup_details.iteritems():
4815 phani.kuma 2183
        order = Order.query.filter_by(pickupRequestNo=pickupNo, doa_logistics_provider_id = provider_id).first()
4741 phani.kuma 2184
        if order == None or order.status != OrderStatus.RET_PICKUP_CONFIRMED:
2185
            #raise TransactionServiceException(102, "No order found for the awb: " + awb)
2186
            continue
2187
        order.status = OrderStatus.RET_RETURN_IN_TRANSIT
2188
        order.statusDescription = "Return order picked up by Courier Company"
2189
        order.doa_pickup_timestamp = return_order_pickup_timestamp
2190
    session.commit()
2191
 
4910 phani.kuma 2192
def get_return_orders_not_picked_up(provider_id):
4741 phani.kuma 2193
    current_time = datetime.datetime.now()
2194
    to_datetime = datetime.datetime(current_time.year, current_time.month, current_time.day)
4815 phani.kuma 2195
    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()
4741 phani.kuma 2196
    return orders_not_picked_up
2197
 
4479 rajveer 2198
def receive_return(order_id, receiveCondition):
2591 chandransh 2199
    order = get_order(order_id)
7199 amar.kumar 2200
    scanFreebie = False
4365 mandeep.dh 2201
 
4452 rajveer 2202
    if order.status in [OrderStatus.DOA_PICKUP_CONFIRMED, OrderStatus.DOA_RETURN_IN_TRANSIT]:
4479 rajveer 2203
        if receiveCondition == 0:
2204
            order.status = OrderStatus.DOA_RECEIVED_PRESTINE
2205
            order.statusDescription = "DOA package received"
2206
        elif receiveCondition == 1:
2207
            order.status = OrderStatus.DOA_RECEIVED_DAMAGED
2208
            order.statusDescription = "DOA received damaged"
2209
        elif receiveCondition == 2:
2210
            order.status = OrderStatus.DOA_LOST_IN_TRANSIT
2211
            order.statusDescription = "DOA lost in transit"
2764 chandransh 2212
        order.received_return_timestamp = datetime.datetime.now()
4495 rajveer 2213
    elif order.status in [OrderStatus.RET_PICKUP_CONFIRMED, OrderStatus.RET_RETURN_IN_TRANSIT]:
2214
        if receiveCondition == 0:
2215
            order.status = OrderStatus.RET_RECEIVED_PRESTINE
2216
            order.statusDescription = "RETURN package received"
2217
        elif receiveCondition == 1:
2218
            order.status = OrderStatus.RET_RECEIVED_DAMAGED
2219
            order.statusDescription = "RETURN received damaged"
2220
        elif receiveCondition == 2:
2221
            order.status = OrderStatus.RET_LOST_IN_TRANSIT
2222
            order.statusDescription = "RETURN lost in transit"
2223
        order.received_return_timestamp = datetime.datetime.now()
4484 rajveer 2224
    elif order.status == OrderStatus.RTO_IN_TRANSIT :
4486 rajveer 2225
        if receiveCondition == 0:
2226
            order.status = OrderStatus.RTO_RECEIVED_PRESTINE
4515 mandeep.dh 2227
            order.statusDescription = "Returned to origin"
4486 rajveer 2228
        elif receiveCondition == 1:
2229
            order.status = OrderStatus.RTO_RECEIVED_DAMAGED
2230
            order.statusDescription = "RTO received damaged"
2231
        elif receiveCondition == 2:
2232
            order.status = OrderStatus.RTO_LOST_IN_TRANSIT
2233
            order.statusDescription = "RTO lost in transit"
2764 chandransh 2234
        order.received_return_timestamp = datetime.datetime.now()
7199 amar.kumar 2235
        if order.freebieItemId:
2236
            scanFreebie = True
2616 chandransh 2237
    else:
2591 chandransh 2238
        return False
5110 mandeep.dh 2239
 
2240
    # For OUR warehouses, we need to scan in items for every return
5944 mandeep.dh 2241
    inventoryClient = InventoryClient().get_client()
2242
    warehouse = inventoryClient.getWarehouse(order.warehouse_id)
6763 amar.kumar 2243
    if warehouse.billingType == BillingType.OURS or warehouse.billingType == BillingType.OURS_EXTERNAL:
5361 mandeep.dh 2244
        scanMap = {
2245
            OrderStatus.RTO_RECEIVED_PRESTINE : ScanType.SALE_RET,
2246
            OrderStatus.RTO_RECEIVED_DAMAGED  : ScanType.SALE_RET_UNUSABLE,
2247
            OrderStatus.RTO_LOST_IN_TRANSIT   : ScanType.LOST_IN_TRANSIT,
2248
            OrderStatus.DOA_RECEIVED_PRESTINE : ScanType.DOA_IN,
2249
            OrderStatus.DOA_RECEIVED_DAMAGED  : ScanType.DOA_IN,
2250
            OrderStatus.DOA_LOST_IN_TRANSIT   : ScanType.LOST_IN_TRANSIT
2251
        }
5110 mandeep.dh 2252
 
5419 mandeep.dh 2253
        if scanMap.has_key(order.status):
2254
            scanType = scanMap[order.status]
5361 mandeep.dh 2255
            lineitem = order.lineitems[0]
5944 mandeep.dh 2256
            catalogClient = CatalogClient().get_client()
5361 mandeep.dh 2257
            item = catalogClient.getItem(lineitem.item_id)
2258
            warehouseClient = WarehouseClient().get_client()
6763 amar.kumar 2259
            if warehouse.billingType == BillingType.OURS or scanType != ScanType.SALE_RET:
2260
                if item.type == ItemType.SERIALIZED:
2261
                    warehouseClient.scanSerializedItemForOrder(lineitem.serial_number, scanType, order.id, order.fulfilmentWarehouseId, lineitem.quantity, order.warehouse_id)
2262
                else:
2263
                    warehouseClient.scanForOrder(None, scanType, lineitem.quantity, order.id, order.fulfilmentWarehouseId, order.warehouse_id)
2264
            if warehouse.billingType == BillingType.OURS_EXTERNAL and scanType == ScanType.SALE_RET:
2265
                warehouseClient.scanForOursExternalSaleReturn(order.id, lineitem.transfer_price)
7199 amar.kumar 2266
            if scanFreebie:
7292 amar.kumar 2267
                warehouseClient.scanfreebie(order.id, order.freebieItemId, 0, scanType)
5558 mandeep.dh 2268
    session.commit()
2591 chandransh 2269
    return True
2270
 
2271
def validate_doa(order_id, is_valid):
2272
    order = get_order(order_id)
4452 rajveer 2273
    if order.status != OrderStatus.DOA_RECEIVED_PRESTINE:
2591 chandransh 2274
        return False
2275
    if is_valid:
2609 chandransh 2276
        order.status = OrderStatus.DOA_CERT_VALID
2277
        order.statusDescription = "DOA Certificate Valid"
2591 chandransh 2278
    else:
2279
        order.status = OrderStatus.DOA_CERT_INVALID
2280
        order.statusDescription = "DOA Certificate Invalid"
3578 mandeep.dh 2281
        update_trust_level(order)
2591 chandransh 2282
    session.commit()
2283
    return True
2284
 
4495 rajveer 2285
def validate_return_product(order_id, is_usable):
2286
    order = get_order(order_id)
2287
    if order.status != OrderStatus.RET_RECEIVED_PRESTINE:
2288
        return False
5110 mandeep.dh 2289
 
2290
    scanType = ScanType.SALE_RET_UNUSABLE
4495 rajveer 2291
    if is_usable:
2292
        order.status = OrderStatus.RET_PRODUCT_USABLE
2293
        order.statusDescription = "Return product usable"
5110 mandeep.dh 2294
        scanType = ScanType.SALE_RET
4495 rajveer 2295
    else:
2296
        order.status = OrderStatus.RET_PRODUCT_UNUSABLE
2297
        order.statusDescription = "Return product unusable"
2298
        update_trust_level(order)
2299
    session.commit()
5110 mandeep.dh 2300
 
2301
    # For OUR warehouses, we need to scan in items for every return
5944 mandeep.dh 2302
    inventoryClient = InventoryClient().get_client()
2303
    warehouse = inventoryClient.getWarehouse(order.warehouse_id)
6786 amar.kumar 2304
    if warehouse.billingType == BillingType.OURS or warehouse.billingType == BillingType.OURS_EXTERNAL:
5110 mandeep.dh 2305
        lineitem = order.lineitems[0]
5944 mandeep.dh 2306
        catalogClient = CatalogClient().get_client()
5361 mandeep.dh 2307
        item = catalogClient.getItem(lineitem.item_id)
5110 mandeep.dh 2308
        warehouse_client = WarehouseClient().get_client()
6786 amar.kumar 2309
        if warehouse.billingType == BillingType.OURS or scanType != ScanType.SALE_RET:
2310
            if item.type == ItemType.SERIALIZED:
2311
                warehouse_client.scanSerializedItemForOrder(lineitem.serial_number, scanType, order.id, order.fulfilmentWarehouseId, lineitem.quantity, order.warehouse_id)
2312
            else:
2313
                warehouse_client.scanForOrder(None, scanType, lineitem.quantity, order.id, order.fulfilmentWarehouseId, order.warehouse_id)
2314
        if scanType == ScanType.SALE_RET and warehouse.billingType == BillingType.OURS_EXTERNAL:
2315
            warehouse_client.scanForOursExternalSaleReturn(order.id, lineitem.transfer_price)        
4495 rajveer 2316
    return True
2317
 
2628 chandransh 2318
def reship_order(order_id):
2319
    """
4484 rajveer 2320
    If the order is in RTO_RECEIVED_PRESTINE or DOA_CERT_INVALID state, it does the following:
2628 chandransh 2321
        1. Creates a new order for processing in the BILLED state. All billing information is saved.
4484 rajveer 2322
        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.
2628 chandransh 2323
 
2324
    If the order is in DOA_CERT_VALID state, it does the following:
2325
        1. Creates a new order for processing in the SUBMITTED_FOR_PROCESSING state.
2326
        2. Creates a return order for the warehouse executive to return the DOA material.
4452 rajveer 2327
        3. Marks the current order as the final DOA_VALID_RESHIPPED state.
2628 chandransh 2328
 
2329
    Returns the id of the newly created order.
2330
 
2331
    Throws an exception if the order with the given id couldn't be found.
2332
 
2333
    Parameters:
2334
     - orderId
2335
    """
2336
    order = get_order(order_id)
4484 rajveer 2337
    if order.status == OrderStatus.RTO_RECEIVED_PRESTINE:
4220 rajveer 2338
        new_order = __clone_order(order, True, order.cod)
4484 rajveer 2339
        order.status = OrderStatus.RTO_RESHIPPED
2628 chandransh 2340
        order.statusDescription = "Order Reshipped"
2341
        session.commit()
3578 mandeep.dh 2342
        update_trust_level(order)
6735 amar.kumar 2343
        __scan_for_reship_order(order_id, new_order)
4486 rajveer 2344
    elif order.status == OrderStatus.RTO_RECEIVED_DAMAGED:
2345
        new_order = __clone_order(order, False, order.cod)
2346
        ret_order = __create_return_order(order)
2347
        order.status = OrderStatus.RTO_DAMAGED_RESHIPPED
2348
        order.statusDescription = "Order Reshipped Received Damaged"
2349
        session.commit()
2350
    elif order.status == OrderStatus.RTO_LOST_IN_TRANSIT:
2351
        new_order = __clone_order(order, False, order.cod)
2352
        order.status = OrderStatus.RTO_LOST_IN_TRANSIT_RESHIPPED
2353
        order.statusDescription = "Order Reshipped Lost In Transit"
2354
        session.commit()
4662 rajveer 2355
    elif order.status == OrderStatus.LOST_IN_TRANSIT:
2356
        new_order = __clone_order(order, False, order.cod)
2357
        order.status = OrderStatus.LOST_IN_TRANSIT_RESHIPPED
2358
        order.statusDescription = "Order Reshipped Lost In Transit"
2359
        session.commit()
2628 chandransh 2360
    elif order.status == OrderStatus.DOA_CERT_INVALID:
4220 rajveer 2361
        new_order = __clone_order(order, True, False)
2628 chandransh 2362
        order.status = OrderStatus.DOA_INVALID_RESHIPPED
2363
        order.statusDescription = "Order Reshipped"
2364
        session.commit()
6735 amar.kumar 2365
        __scan_for_reship_order(order_id, new_order)
2628 chandransh 2366
    elif order.status == OrderStatus.DOA_CERT_VALID:
4220 rajveer 2367
        new_order = __clone_order(order, False, False)
2628 chandransh 2368
        ret_order = __create_return_order(order)
4452 rajveer 2369
        order.status = OrderStatus.DOA_VALID_RESHIPPED
2628 chandransh 2370
        order.statusDescription = "Order Reshipped"
2371
        session.commit()
4479 rajveer 2372
    elif order.status == OrderStatus.DOA_RECEIVED_DAMAGED:
2373
        new_order = __clone_order(order, False, False)
2374
        ret_order = __create_return_order(order)
2375
        order.status = OrderStatus.DOA_RESHIPPED_RCVD_DAMAGED
2376
        order.statusDescription = "Order Reshipped Received Damaged"
2377
        session.commit()
2378
    elif order.status == OrderStatus.DOA_LOST_IN_TRANSIT:
2379
        new_order = __clone_order(order, False, False)
2380
        order.status = OrderStatus.DOA_RESHIPPED_LOST_IN_TRANSIT
2381
        order.statusDescription = "Order Reshipped Lost In Transit"
2382
        session.commit()
4614 rajveer 2383
    elif order.status == OrderStatus.RET_PRODUCT_USABLE:
5620 mandeep.dh 2384
        new_order = __clone_order(order, False, False)
4614 rajveer 2385
        order.status = OrderStatus.RET_PRODUCT_USABLE_RESHIPPED
4495 rajveer 2386
        order.statusDescription = "Order Reshipped"
2387
        session.commit()
4614 rajveer 2388
    elif order.status == OrderStatus.RET_PRODUCT_UNUSABLE:
4495 rajveer 2389
        new_order = __clone_order(order, False, False)
2390
        ret_order = __create_return_order(order)
4614 rajveer 2391
        order.status = OrderStatus.RET_PRODUCT_UNUSABLE_RESHIPPED
4495 rajveer 2392
        order.statusDescription = "Order Reshipped"
2393
        session.commit()
2394
    elif order.status == OrderStatus.RET_RECEIVED_DAMAGED:
2395
        new_order = __clone_order(order, False, False)
2396
        ret_order = __create_return_order(order)
2397
        order.status = OrderStatus.RET_RESHIPPED_RCVD_DAMAGED
2398
        order.statusDescription = "Order Reshipped Received Damaged"
2399
        session.commit()
2400
    elif order.status == OrderStatus.RET_LOST_IN_TRANSIT:
2401
        new_order = __clone_order(order, False, False)
2402
        order.status = OrderStatus.RET_RESHIPPED_LOST_IN_TRANSIT
2403
        order.statusDescription = "Order Reshipped Lost In Transit"
2404
        session.commit()
2628 chandransh 2405
    else:
2406
        raise TransactionServiceException(112, "This order can't be reshipped")
2407
 
2764 chandransh 2408
    order.reship_timestamp = datetime.datetime.now()
2628 chandransh 2409
    order.new_order_id = new_order.id
2410
    session.commit()
2411
 
2412
    return new_order.id
2413
 
6735 amar.kumar 2414
def __scan_for_reship_order(order_id, new_order):
2415
    inventoryClient = InventoryClient().get_client()
2416
    warehouse = inventoryClient.getWarehouse(new_order.warehouse_id)
2417
    if warehouse.billingType == BillingType.OURS:
2418
        warehouseClient = WarehouseClient().get_client()
2419
        inventoryItem = warehouseClient.getInventoryItemFromOrder(order_id)
2420
        warehouseClient.scanForOrder(inventoryItem, ScanType.SALE, new_order.lineitems[0].quantity, new_order.id, new_order.fulfilmentWarehouseId, new_order.warehouse_id)
7199 amar.kumar 2421
    if order.freebieItemId:
2422
        warehouseClient = WarehouseClient().get_client()
2423
        inventoryItem = warehouseClient.reshipfreebie(order_id, new_order.id, new_order.freebieItemId, ScanType.SALE)
6735 amar.kumar 2424
 
3226 chandransh 2425
def refund_order(order_id, refunded_by, reason):
2628 chandransh 2426
    """
4484 rajveer 2427
    If the order is in RTO_RECEIVED_PRESTINE, DOA_CERT_VALID or DOA_CERT_INVALID state, it does the following:
2628 chandransh 2428
        1. Creates a refund request for batch processing.
2429
        2. Creates a return order for the warehouse executive to return the shipped material.
4484 rajveer 2430
        3. Marks the current order as RTO_REFUNDED, DOA_VALID_REFUNDED or DOA_INVALID_REFUNDED final states.
2628 chandransh 2431
 
2432
    If the order is in SUBMITTED_FOR_PROCESSING or INVENTORY_LOW state, it does the following:
2433
        1. Creates a refund request for batch processing.
3226 chandransh 2434
        2. Cancels the reservation of the item in the warehouse.
2435
        3. Marks the current order as the REFUNDED final state.
2628 chandransh 2436
 
3226 chandransh 2437
    For all COD orders, if the order is in INIT, SUBMITTED_FOR_PROCESSING or INVENTORY_LOW state, it does the following:
2438
        1. Cancels the reservation of the item in the warehouse.
2439
        2. Marks the current order as CANCELED.
2440
 
2441
    In all cases, it updates the reason for cancellation or refund and the person who performed the action.
2442
 
2443
    Returns True if it is successful, False otherwise.
2628 chandransh 2444
 
2445
    Throws an exception if the order with the given id couldn't be found.
2446
 
2447
    Parameters:
3226 chandransh 2448
     - order_id
2449
     - refunded_by
2450
     - reason
2628 chandransh 2451
    """
3414 chandransh 2452
    logging.info("Refunding order id: " + str(order_id))
2628 chandransh 2453
    order = get_order(order_id)
3186 chandransh 2454
 
3226 chandransh 2455
    if order.cod:
3414 chandransh 2456
        logging.info("Refunding COD order with status " + str(order.status))
4662 rajveer 2457
        status_transition = { OrderStatus.LOST_IN_TRANSIT : OrderStatus.LOST_IN_TRANSIT_REFUNDED,
2458
                     OrderStatus.RTO_RECEIVED_PRESTINE : OrderStatus.RTO_REFUNDED,
4486 rajveer 2459
                     OrderStatus.RTO_RECEIVED_DAMAGED : OrderStatus.RTO_DAMAGED_REFUNDED,
2460
                     OrderStatus.RTO_LOST_IN_TRANSIT : OrderStatus.RTO_LOST_IN_TRANSIT_REFUNDED,
3366 chandransh 2461
                     OrderStatus.DOA_CERT_INVALID : OrderStatus.DOA_INVALID_REFUNDED,
2462
                     OrderStatus.DOA_CERT_VALID : OrderStatus.DOA_VALID_REFUNDED,
4479 rajveer 2463
                     OrderStatus.DOA_RECEIVED_DAMAGED : OrderStatus.DOA_REFUNDED_RCVD_DAMAGED,
2464
                     OrderStatus.DOA_LOST_IN_TRANSIT : OrderStatus.DOA_REFUNDED_LOST_IN_TRANSIT,
4495 rajveer 2465
                     OrderStatus.RET_PRODUCT_UNUSABLE : OrderStatus.RET_PRODUCT_UNUSABLE_REFUNDED,
2466
                     OrderStatus.RET_PRODUCT_USABLE : OrderStatus.RET_PRODUCT_USABLE_REFUNDED,
2467
                     OrderStatus.RET_RECEIVED_DAMAGED : OrderStatus.RET_REFUNDED_RCVD_DAMAGED,
2468
                     OrderStatus.RET_LOST_IN_TRANSIT : OrderStatus.RET_REFUNDED_LOST_IN_TRANSIT,
4682 rajveer 2469
                     OrderStatus.COD_VERIFICATION_PENDING : OrderStatus.COD_VERIFICATION_FAILED,
2470
                     OrderStatus.SUBMITTED_FOR_PROCESSING : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2471
                     OrderStatus.INVENTORY_LOW : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2472
                     OrderStatus.LOW_INV_PO_RAISED : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2473
                     OrderStatus.LOW_INV_REVERSAL_IN_PROCESS : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2474
                     OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2475
                     OrderStatus.ACCEPTED : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2476
                     OrderStatus.BILLED : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
4247 rajveer 2477
                     OrderStatus.CANCEL_REQUEST_CONFIRMED : OrderStatus.CANCELLED_ON_CUSTOMER_REQUEST
3366 chandransh 2478
                     }
2479
        if order.status not in status_transition.keys():
2480
            raise TransactionServiceException(114, "This order can't be refunded")
7386 anupam.sin 2481
 
5199 mandeep.dh 2482
        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]:
3226 chandransh 2483
            __update_inventory_reservation(order)
2484
            order.statusDescription = "Order Cancelled"
3415 chandransh 2485
        elif order.status == OrderStatus.BILLED:
3413 chandransh 2486
            __create_return_order(order)
2487
            order.statusDescription = "Order Cancelled"
4486 rajveer 2488
        elif order.status in [OrderStatus.RTO_RECEIVED_PRESTINE, OrderStatus.RTO_RECEIVED_DAMAGED, OrderStatus.RTO_LOST_IN_TRANSIT]:
5386 phani.kuma 2489
            if order.status != OrderStatus.RTO_LOST_IN_TRANSIT:
2490
                __create_return_order(order)
4486 rajveer 2491
            order.statusDescription = "RTO Refunded"
4662 rajveer 2492
        elif order.status in [OrderStatus.LOST_IN_TRANSIT]:
5386 phani.kuma 2493
            #__create_return_order(order)
4662 rajveer 2494
            order.statusDescription = "Lost in Transit Refunded"
4479 rajveer 2495
        elif order.status in [OrderStatus.DOA_CERT_INVALID, OrderStatus.DOA_CERT_VALID, OrderStatus.DOA_RECEIVED_DAMAGED, OrderStatus.DOA_LOST_IN_TRANSIT] :
5386 phani.kuma 2496
            if order.status != OrderStatus.DOA_LOST_IN_TRANSIT:
2497
                __create_return_order(order)
3226 chandransh 2498
            __create_refund(order)
4495 rajveer 2499
            order.statusDescription = "DOA Refunded"
2500
        elif order.status in [OrderStatus.RET_PRODUCT_UNUSABLE, OrderStatus.RET_PRODUCT_USABLE, OrderStatus.RET_RECEIVED_DAMAGED, OrderStatus.RET_LOST_IN_TRANSIT] :
5386 phani.kuma 2501
            if order.status != OrderStatus.RET_LOST_IN_TRANSIT:
2502
                __create_return_order(order)
4495 rajveer 2503
            __create_refund(order)
2504
            order.statusDescription = "Return Refunded"
4247 rajveer 2505
        elif order.status == OrderStatus.CANCEL_REQUEST_CONFIRMED:
5199 mandeep.dh 2506
            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]:
4247 rajveer 2507
                __update_inventory_reservation(order)
2508
                order.statusDescription = "Order Cancelled on customer request"
2509
            elif order.previousStatus == OrderStatus.BILLED:
2510
                __create_return_order(order)
2511
                order.statusDescription = "Order Cancelled on customer request"
6668 amar.kumar 2512
                order.received_return_timestamp = datetime.datetime.now()
3226 chandransh 2513
    else:
4662 rajveer 2514
        status_transition = {OrderStatus.LOST_IN_TRANSIT : OrderStatus.LOST_IN_TRANSIT_REFUNDED,
2515
                     OrderStatus.RTO_RECEIVED_PRESTINE : OrderStatus.RTO_REFUNDED,
4486 rajveer 2516
                     OrderStatus.RTO_RECEIVED_DAMAGED : OrderStatus.RTO_DAMAGED_REFUNDED,
2517
                     OrderStatus.RTO_LOST_IN_TRANSIT : OrderStatus.RTO_LOST_IN_TRANSIT_REFUNDED,
3366 chandransh 2518
                     OrderStatus.DOA_CERT_INVALID : OrderStatus.DOA_INVALID_REFUNDED,
2519
                     OrderStatus.DOA_CERT_VALID : OrderStatus.DOA_VALID_REFUNDED,
4479 rajveer 2520
                     OrderStatus.DOA_RECEIVED_DAMAGED : OrderStatus.DOA_REFUNDED_RCVD_DAMAGED,
2521
                     OrderStatus.DOA_LOST_IN_TRANSIT : OrderStatus.DOA_REFUNDED_LOST_IN_TRANSIT,
4495 rajveer 2522
                     OrderStatus.RET_PRODUCT_UNUSABLE : OrderStatus.RET_PRODUCT_UNUSABLE_REFUNDED,
2523
                     OrderStatus.RET_PRODUCT_USABLE : OrderStatus.RET_PRODUCT_USABLE_REFUNDED,
2524
                     OrderStatus.RET_RECEIVED_DAMAGED : OrderStatus.RET_REFUNDED_RCVD_DAMAGED,
2525
                     OrderStatus.RET_LOST_IN_TRANSIT : OrderStatus.RET_REFUNDED_LOST_IN_TRANSIT,
4682 rajveer 2526
                     OrderStatus.SUBMITTED_FOR_PROCESSING : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2527
                     OrderStatus.INVENTORY_LOW : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2528
                     OrderStatus.LOW_INV_PO_RAISED : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2529
                     OrderStatus.LOW_INV_REVERSAL_IN_PROCESS : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2530
                     OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2531
                     OrderStatus.ACCEPTED : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2532
                     OrderStatus.BILLED : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
4247 rajveer 2533
                     OrderStatus.CANCEL_REQUEST_CONFIRMED : OrderStatus.CANCELLED_ON_CUSTOMER_REQUEST,
2534
                     OrderStatus.PAYMENT_FLAGGED : OrderStatus.PAYMENT_FLAGGED_DENIED
3366 chandransh 2535
                     }
2536
        if order.status not in status_transition.keys():
2537
            raise TransactionServiceException(114, "This order can't be refunded")
2538
 
4495 rajveer 2539
        if order.status in [OrderStatus.RTO_RECEIVED_PRESTINE, OrderStatus.RTO_RECEIVED_DAMAGED, OrderStatus.RTO_LOST_IN_TRANSIT] :
5386 phani.kuma 2540
            if order.status != OrderStatus.RTO_LOST_IN_TRANSIT:
2541
                __create_return_order(order)
3226 chandransh 2542
            __create_refund(order)
4495 rajveer 2543
            order.statusDescription = "RTO Refunded"
4662 rajveer 2544
        elif order.status in [OrderStatus.LOST_IN_TRANSIT]:
5386 phani.kuma 2545
            #__create_return_order(order)
4662 rajveer 2546
            __create_refund(order)
2547
            order.statusDescription = "Lost in Transit Refunded"
4495 rajveer 2548
        elif order.status in [OrderStatus.DOA_CERT_INVALID, OrderStatus.DOA_CERT_VALID, OrderStatus.DOA_RECEIVED_DAMAGED, OrderStatus.DOA_LOST_IN_TRANSIT] :
5386 phani.kuma 2549
            if order.status != OrderStatus.DOA_LOST_IN_TRANSIT:
2550
                __create_return_order(order)
4495 rajveer 2551
            __create_refund(order)
2552
            order.statusDescription = "DOA Refunded"
2553
        elif order.status in [OrderStatus.RET_PRODUCT_UNUSABLE, OrderStatus.RET_PRODUCT_USABLE, OrderStatus.RET_RECEIVED_DAMAGED, OrderStatus.RET_LOST_IN_TRANSIT] :
5386 phani.kuma 2554
            if order.status != OrderStatus.RET_LOST_IN_TRANSIT:
2555
                __create_return_order(order)
4495 rajveer 2556
            __create_refund(order)
2557
            order.statusDescription = "Return Refunded"
5199 mandeep.dh 2558
        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]:
3226 chandransh 2559
            __update_inventory_reservation(order)
2560
            order.statusDescription = "Order Refunded"
4247 rajveer 2561
        elif order.status == OrderStatus.CANCEL_REQUEST_CONFIRMED:
5272 mandeep.dh 2562
            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]:
4672 rajveer 2563
                if order.previousStatus == OrderStatus.ACCEPTED:
2564
                    __create_refund(order)
4247 rajveer 2565
                __update_inventory_reservation(order)
2566
                order.statusDescription = "Order Cancelled on customer request"
2567
            elif order.previousStatus == OrderStatus.BILLED:
2568
                __create_return_order(order)
2569
                __create_refund(order)
2570
                order.statusDescription = "Order Cancelled on customer request"
6668 amar.kumar 2571
                order.received_return_timestamp = datetime.datetime.now()
4247 rajveer 2572
        elif order.status == OrderStatus.PAYMENT_FLAGGED:
2573
            __update_inventory_reservation(order)
2574
            order.statusDescription = "Order Cancelled due to payment flagged"
3195 chandransh 2575
 
4873 mandeep.dh 2576
    # For orders that are cancelled after being billed, we need to scan in the scanned out
2577
    # inventory item and change availability accordingly
5944 mandeep.dh 2578
    inventoryClient = InventoryClient().get_client()
2579
    warehouse = inventoryClient.getWarehouse(order.warehouse_id)
6786 amar.kumar 2580
    if warehouse.billingType == BillingType.OURS or warehouse.billingType == BillingType.OURS_EXTERNAL:
4873 mandeep.dh 2581
        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]):
2582
            lineitem = order.lineitems[0]
5944 mandeep.dh 2583
            catalogClient = CatalogClient().get_client()
5177 mandeep.dh 2584
            item = catalogClient.getItem(lineitem.item_id)
5361 mandeep.dh 2585
            warehouseClient = WarehouseClient().get_client()
6786 amar.kumar 2586
            if warehouse.billingType == BillingType.OURS:
2587
                if ItemType.SERIALIZED == item.type:
2588
                    warehouseClient.scanSerializedItemForOrder(lineitem.serial_number, ScanType.SALE_RET, order.id, order.fulfilmentWarehouseId, lineitem.quantity, order.warehouse_id)
2589
                else:
2590
                    warehouseClient.scanForOrder(None, ScanType.SALE_RET, lineitem.quantity, order.id, order.fulfilmentWarehouseId, order.warehouse_id)
2591
            if warehouse.billingType == BillingType.OURS_EXTERNAL:
2592
                warehouseClient.scanForOursExternalSaleReturn(order.id, lineitem.transfer_price)            
4873 mandeep.dh 2593
 
7386 anupam.sin 2594
    if order.source == 2 and order.status in (OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.ACCEPTED, OrderStatus.INVENTORY_LOW):
2595
        __push_store_collection_to_hotspot(order, "advanceRefund", -order.advanceAmount)
2596
 
3195 chandransh 2597
    order.status = status_transition[order.status]
2598
    order.refund_timestamp = datetime.datetime.now()
3226 chandransh 2599
    order.refunded_by = refunded_by
2600
    order.refund_reason = reason
7386 anupam.sin 2601
 
2602
 
2628 chandransh 2603
    session.commit()
2604
    return True
2605
 
3186 chandransh 2606
def __update_inventory_reservation(order):
3191 chandransh 2607
    '''
2608
    Reduce the reservation count for all line items of the given order.
2609
    '''
3186 chandransh 2610
    try:
5944 mandeep.dh 2611
        inventoryClient = InventoryClient().get_client()
3186 chandransh 2612
        for lineitem in order.lineitems:
5966 rajveer 2613
            inventoryClient.reduceReservationCount(lineitem.item_id, order.fulfilmentWarehouseId, sourceId, order.id, lineitem.quantity)
3186 chandransh 2614
    except:
2615
        print "Unable to reduce reservation count"
2616
 
4220 rajveer 2617
def __clone_order(order, should_copy_billing_info, is_cod):
2628 chandransh 2618
    current_time = datetime.datetime.now()
2619
    new_order = Order()
2620
    new_order.customer_id = order.customer_id
2621
    new_order.customer_name = order.customer_name
2622
    new_order.customer_city = order.customer_city
2623
    new_order.customer_state = order.customer_state
2624
    new_order.customer_mobilenumber = order.customer_mobilenumber
2625
    new_order.customer_pincode = order.customer_pincode
2626
    new_order.customer_address1 = order.customer_address1
2627
    new_order.customer_address2 = order.customer_address2
2628
    new_order.customer_email = order.customer_email
2629
    new_order.total_amount = order.total_amount
6318 rajveer 2630
    new_order.gvAmount = order.gvAmount
2628 chandransh 2631
    new_order.total_weight = order.total_weight
2632
    new_order.status = OrderStatus.SUBMITTED_FOR_PROCESSING
2633
    new_order.statusDescription = 'Submitted for Processing'
2634
    new_order.created_timestamp = current_time
5062 varun.gupt 2635
    new_order.originalOrderId = order.originalOrderId if order.originalOrderId is not None else order.id 
2628 chandransh 2636
 
2637
    new_order.transaction = order.transaction
4220 rajveer 2638
    new_order.cod = is_cod
5527 anupam.sin 2639
    new_order.orderType = order.orderType
7199 amar.kumar 2640
    new_order.freebieItemId = order.freebieItemId
2628 chandransh 2641
    for line_item in order.lineitems:
2642
        litem = LineItem()
2643
        litem.item_id = line_item.item_id
2644
        litem.productGroup = line_item.productGroup
2645
        litem.brand = line_item.brand
2646
        if line_item.model_number:
2647
            litem.model_number = line_item.model_number
2648
        if line_item.model_name:    
2649
            litem.model_name = line_item.model_name
2650
        if line_item.color:
2651
            litem.color = line_item.color
2652
        if line_item.extra_info:
2653
            litem.extra_info = line_item.extra_info
2654
        litem.quantity = line_item.quantity
2655
        litem.unit_price = line_item.unit_price
2656
        litem.unit_weight = line_item.unit_weight
2657
        litem.total_price = line_item.total_price
2658
        litem.total_weight = line_item.total_weight
2659
        litem.transfer_price = line_item.transfer_price
6751 amar.kumar 2660
        litem.nlc = line_item.nlc
4840 mandeep.dh 2661
        litem.dealText = line_item.dealText
6423 amit.gupta 2662
        litem.vatRate = line_item.vatRate
2628 chandransh 2663
        litem.order = new_order
6912 anupam.sin 2664
 
2665
    if order.insurer > 0:
2666
        new_order.insurer = order.insurer
2667
        new_order.insuranceAmount = order.insuranceAmount
2668
        newDetail = InsuranceDetailForOrder()
2669
        oldDetail = InsuranceDetailForOrder.get_by(order_id = order.id)
2670
        newDetail.dob = oldDetail.dob
2671
        newDetail.guardianName = oldDetail.guardianName
2672
        newDetail.order = new_order
2673
 
2628 chandransh 2674
    logistics_client = LogisticsClient().get_client()
2675
    item_id = new_order.lineitems[0].item_id
5785 mandeep.dh 2676
    logistics_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.
6726 rajveer 2677
    logistics_info.shippingTime = adjust_delivery_time(current_time, logistics_info.shippingTime)
2628 chandransh 2678
    logistics_info.deliveryTime = adjust_delivery_time(current_time, logistics_info.deliveryTime)
6726 rajveer 2679
    logistics_info.deliveryDelay = adjust_delivery_time(current_time, (logistics_info.shippingTime + logistics_info.deliveryDelay))
2628 chandransh 2680
    new_order.warehouse_id = logistics_info.warehouseId
5110 mandeep.dh 2681
    new_order.fulfilmentWarehouseId = logistics_info.fulfilmentWarehouseId
2628 chandransh 2682
    new_order.logistics_provider_id = logistics_info.providerId
2683
    new_order.airwaybill_no = logistics_info.airway_billno
2684
    new_order.tracking_id = new_order.airwaybill_no
6726 rajveer 2685
 
2686
    order.courier_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryDelay)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
2687
    new_order.expected_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryTime)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
3986 chandransh 2688
    new_order.promised_delivery_time = new_order.expected_delivery_time
6629 anupam.sin 2689
    new_order.expected_shipping_time = (current_time + datetime.timedelta(days=logistics_info.shippingTime)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
2690
    new_order.promised_shipping_time = new_order.expected_shipping_time
2691
 
2628 chandransh 2692
    if should_copy_billing_info:
5388 phani.kuma 2693
        new_order.vendorId = order.vendorId
2628 chandransh 2694
        new_order.invoice_number = order.invoice_number
2695
        new_order.billed_by = order.billed_by
2696
        new_order.warehouse_id = order.warehouse_id
5110 mandeep.dh 2697
        new_order.fulfilmentWarehouseId = order.fulfilmentWarehouseId
5620 mandeep.dh 2698
        new_order.jacket_number = order.jacket_number
2699
        new_order.lineitems[0].serial_number = order.lineitems[0].serial_number
2700
        new_order.lineitems[0].item_number   = order.lineitems[0].item_number
2628 chandransh 2701
        new_order.accepted_timestamp = current_time
2702
        new_order.billing_timestamp = current_time    
2703
        new_order.status = OrderStatus.BILLED
2704
        new_order.statusDescription = 'Order Billed'
5966 rajveer 2705
    else:
2706
        session.commit()       
5944 mandeep.dh 2707
        inventoryClient = InventoryClient().get_client()
5966 rajveer 2708
        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)
2628 chandransh 2709
 
2710
    return new_order
2711
 
2712
def __create_return_order(order):
2687 chandransh 2713
    ret_order = ReturnOrder(order)
2628 chandransh 2714
    return ret_order
2715
 
2716
def __create_refund(order):
4078 chandransh 2717
    payment_client = PaymentClient().get_client()
2718
    payment_client.createRefund(order.id, order.transaction.id, order.total_amount)
2747 chandransh 2719
    return
2628 chandransh 2720
 
2536 chandransh 2721
def __get_order_address(order):
2722
    address = order.customer_name + "\n" + order.customer_address1 + "\n"
2723
    if order.customer_address2:
2724
        address = address + order.customer_address2 + "\n"
2725
    address = address + order.customer_city + "\n"
2726
    address = address + order.customer_state + "\n"
2727
    address = address + "PIN " + order.customer_pincode + "\n"
2728
    address = address + "Phone: " + order.customer_mobilenumber
2729
    return address
2730
 
5767 rajveer 2731
def __get_store_address(store):
2732
    address = store.name + "\n" + store.line1 + "\n"
2733
    if store.line2:
2734
        address = address + store.line2 + "\n"
2735
    address = address + store.city + "\n"
2736
    address = address + store.state + "\n"
5802 rajveer 2737
    address = address + "PIN - " + store.pin + "\n"
5793 rajveer 2738
    if store.phone:
5802 rajveer 2739
        address = address + "Phone - " + store.phone + "\n"
5855 rajveer 2740
    address = address +  "Store timings - 11AM to 8PM (7 days)\n"
5767 rajveer 2741
    return address
2742
 
5793 rajveer 2743
def __get_store_address_html(store):
2744
    address = store.name + "<br>" + store.line1 + "<br>"
2745
    if store.line2:
2746
        address = address + store.line2 + "<br>"
2747
    address = address + store.city + "<br>"
2748
    address = address + store.state + "<br>"
5802 rajveer 2749
    address = address + "PIN - " + store.pin + "<br>"
5793 rajveer 2750
    if store.phone:
5802 rajveer 2751
        address = address + "Phone - " + store.phone + "<br>"
5855 rajveer 2752
    address = address +  "Store timings - 7 days: 11AM to 8PM  (7 days)<br>"
5793 rajveer 2753
    return address
2754
 
4815 phani.kuma 2755
def __generate_return_advice(order, warehouse, provider, filename):
2756
    if warehouse.id == 7:
7181 rajveer 2757
        executive = 'Shiv Kumar'
4815 phani.kuma 2758
    else:
4966 phani.kuma 2759
        executive = 'Dinesh Kumar'
2536 chandransh 2760
    pdf = Canvas(filename)
2761
    pdf.setFont('Times-Bold',16)
2762
    address_text = pdf.beginText(inch, PAGE_HEIGHT - inch)
2763
    address_text.textLine("To")
4815 phani.kuma 2764
    address_text.textLine(executive)
2536 chandransh 2765
    for line in warehouse.location.split("\n"):
2766
        address_text.textLine(line)
2767
    address_text.textLine("PIN " + warehouse.pincode)
2768
    pdf.drawText(address_text)
2769
 
2770
    pdf.setFont('Times-Roman',12)
2771
    order_text = pdf.beginText(inch, PAGE_HEIGHT - 4 * inch)
3051 chandransh 2772
    order_text.textLine("Pickup CODE: " + provider.details[DeliveryType.PREPAID].accountNo)
2536 chandransh 2773
    lineitem = order.lineitems[0] 
4234 rajveer 2774
    order_text.textLine("Content : " + lineitem.brand + " " + str(lineitem.model_number) + " " + str(lineitem.color))
2536 chandransh 2775
    order_text.textLine("Declared Value: Rs. " + str(order.total_amount))
2776
    order_text.textLine("Order ID : " + str(order.id))
2777
    pdf.drawText(order_text)
2778
    pdf.showPage()
2779
    pdf.save()
2780
    return filename
2781
 
7386 anupam.sin 2782
def __push_store_collection_to_hotspot(order, ctype, amount):
7385 rajveer 2783
    try:
2784
        ts = order.created_timestamp
2785
        store =  get_hotspot_store(order.storeId, "")
2786
        storeName = store.hotspotId
2787
        store_string = "<Store>" + storeName + "</Store>"
2788
        order_string = "<OrderID>" + str(order.id) + "</OrderID>"
2789
        product_string = "<Product>" + str(order.lineitems[0]) + "</Product>"
7386 anupam.sin 2790
        collection_type = "<CollectionType>" + ctype + "</CollectionType>"
2791
        amount_string = "<AdvanceAmount>" + amount + "</AdvanceAmount>"
7385 rajveer 2792
        date_string = "<TimeStamp>" + ts.strftime("%Y%m%d%H%M%S") + "</TimeStamp>"
2793
        cash_string = "<CashAmount>" + order.advanceAmount + "</CashAmount>"
2794
        card_string = "<CardAmount>" + "0" + "</CardAmount>"
2795
 
2796
        #advance, saleClosure, advanceRefund, saleRefund
2797
 
2798
        conn = httplib.HTTPConnection("182.71.104.186")
2799
        XML="""
2800
        <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
2801
          <soap:Body>
2802
            <SaholicAdvanceTransfer xmlns="http://tempuri.org/">
2803
        """
2804
 
2805
        XML = XML + store_string + order_string + product_string + collection_type + amount_string + cash_string + card_string + date_string 
2806
 
2807
        footer = """
2808
            </SaholicAdvanceTransfer>
2809
          </soap:Body>
2810
        </soap:Envelope>
2811
        """
2812
        XML = XML + footer
2813
 
2814
        params = urllib.urlencode({'op': 'SaholicAdvanceTransfer'})
2815
        headers = { "Content-type": "text/xml", "Content-Length": "%d" % len(XML)}
2816
        conn.request("POST", "/loaddetect/Service.asmx?"+params, "", headers)
2817
        conn.send(XML)
2818
        response = conn.getresponse()
2819
        print response.status, response.reason
2820
        resp = response.read()
2821
        conn.close()
2822
        print resp
2823
        if "Saved Successfully" in resp:
2824
            return True
2825
        elif "Error in Saving Data" in resp:
2826
            return False
2827
        else: 
2828
            return False
2829
    except Exception as e:
2830
        print e
2831
        return False
2832
 
7344 rajveer 2833
def __push_collection_to_hotspot(order, type, storeOrder = False):
5806 rajveer 2834
    try:
7344 rajveer 2835
        storeName = '109'
2836
        if storeOrder:
2837
            store =  get_hotspot_store(order.storeId, "")
2838
            storeName = store.hotspotId
2839
            storeName = '109'
2840
        else:
2841
            logistics_client = LogisticsClient().get_client()
2842
            store = logistics_client.getPickupStore(order.pickupStoreId)
2843
            storeName = store.hotspotId
2844
        store_string = "<store>" + storeName + "</store>"
5806 rajveer 2845
        order_string = "<orderno>" + str(order.id) + "</orderno>"
2846
        collection_type = "<Type>" + type + "</Type>"
5833 rajveer 2847
        payment_mode = get_order_attribute_value(order.id, "PAYMENT_MODE")
5806 rajveer 2848
        if type == "SALE":
7344 rajveer 2849
            if storeOrder:
7350 rajveer 2850
                amount = int(order.advanceAmount)
2851
                ts = order.created_timestamp
7344 rajveer 2852
            else:
2853
                amount = int(order.total_amount-order.gvAmount)
7350 rajveer 2854
                ts = order.delivery_timestamp
5806 rajveer 2855
        if type == "SALE RETURN":
7344 rajveer 2856
            if storeOrder:
7350 rajveer 2857
                amount = -int(order.advanceAmount)
7344 rajveer 2858
            else:
2859
                amount = -int(order.total_amount-order.gvAmount)
5806 rajveer 2860
            ts = order.refund_timestamp
2861
        if payment_mode == "Cash":
2862
            cash_string = "<cash>" + str(amount) + "</cash>"
2863
            card_string = "<hdfc>0</hdfc>"
2864
        if payment_mode == "Card":
2865
            cash_string = "<cash>0</cash>"
2866
            card_string = "<hdfc>" + str(amount) + "</hdfc>"
2867
        date_string = "<date>" + ts.strftime("%Y%m%d") + "</date>"
2868
        time_string = "<time>" + ts.strftime("%H%M%S") + "</time>"
2869
 
7254 rajveer 2870
        conn = httplib.HTTPConnection("182.71.104.186")
5806 rajveer 2871
        XML="""
2872
        <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
2873
          <soap:Body>
2874
            <SaholicDataTransfer xmlns="http://tempuri.org/">
2875
        """
2876
 
2877
        XML = XML + store_string + order_string + collection_type + cash_string + card_string + date_string + time_string 
2878
 
2879
        footer = """
2880
            </SaholicDataTransfer>
2881
          </soap:Body>
2882
        </soap:Envelope>
2883
        """
2884
        XML = XML + footer
2885
 
2886
        params = urllib.urlencode({'op': 'SaholicDataTransfer'})
2887
        headers = { "Content-type": "text/xml", "Content-Length": "%d" % len(XML)}
2888
        conn.request("POST", "/loaddetect/Service.asmx?"+params, "", headers)
2889
        conn.send(XML)
2890
        response = conn.getresponse()
2891
        print response.status, response.reason
2892
        resp = response.read()
2893
        conn.close()
2894
        print resp
2895
        if "Saved Successfully" in resp:
2896
            return True
2897
        elif "Error in Saving Data" in resp:
2898
            return False
2899
        else: 
2900
            return False
2901
    except Exception as e:
2902
        print e
2903
        return False
2904
 
2697 chandransh 2905
def get_return_orders(warehouse_id, from_date, to_date):
2906
    query = ReturnOrder.query.filter_by(processedStatus = False)
2907
    if warehouse_id != -1:
2908
        query = query.filter_by(warehouseId = warehouse_id)
2909
    if from_date:
4118 chandransh 2910
        query = query.filter(ReturnOrder.createdAt >from_date)
2697 chandransh 2911
    if to_date:
4118 chandransh 2912
        query = query.filter(ReturnOrder.createdAt < to_date)
2697 chandransh 2913
    return [return_order.to_thrift_object() for return_order in query.all()]
2914
 
5481 phani.kuma 2915
def get_all_return_orders(onlyNotProcessed, from_date, to_date):
2916
    query = ReturnOrder.query
2917
    if onlyNotProcessed:
2918
        query = query.filter_by(processedStatus = False)
2919
    if from_date:
2920
        query = query.filter(ReturnOrder.createdAt >= from_date)
2921
    if to_date:
2922
        query = query.filter(ReturnOrder.createdAt <= to_date)
2923
    return [return_order.to_thrift_object() for return_order in query.all()]
2924
 
2700 chandransh 2925
def get_return_order(id):
2926
    ret_order = ReturnOrder.get_by(orderId = id)
2927
    if ret_order is None:
2928
        raise TransactionServiceException(116, "No return order found for the given order id")
2929
    return ret_order.to_thrift_object()
2930
 
2697 chandransh 2931
def process_return(ret_order_id):
2932
    ret_order = ReturnOrder.get_by(orderId = ret_order_id)
2933
    if ret_order is None:
2934
        raise TransactionServiceException(116, "No return order found for the given order id")
2935
    ret_order.processedStatus = True
2701 chandransh 2936
    ret_order.processedAt = datetime.datetime.now()
2697 chandransh 2937
    session.commit()
2938
 
4757 mandeep.dh 2939
def update_orders_as_PORaised(itemIdQuantityMap, purchaseOrderId, warehouseId):
2940
    """
2941
    Updates orders as PO raised. Also updates purchase order id in orders. Pass a map of items mapped to
2942
    the quantities for which the PO is raised.
2943
 
2944
    Parameters:
2945
     - itemIdQuantityMap
2946
     - purchaseOrderId
2947
     - warehouseId
2948
    """
3451 chandransh 2949
    query = Order.query.with_lockmode("update").filter_by(warehouse_id=warehouseId)
4757 mandeep.dh 2950
    query = query.filter(or_(Order.status == OrderStatus.SUBMITTED_FOR_PROCESSING, Order.status == OrderStatus.INVENTORY_LOW))
2819 chandransh 2951
    query = query.filter_by(purchase_order_id=None)
2952
    query = query.order_by(Order.created_timestamp)
2953
    pending_orders = query.all()
4586 mandeep.dh 2954
 
2955
    for order in pending_orders:
4757 mandeep.dh 2956
        lineitem = order.lineitems[0]
2957
        if itemIdQuantityMap.has_key(lineitem.item_id):
2958
            if itemIdQuantityMap[lineitem.item_id] >= lineitem.quantity:
2959
                order.status = OrderStatus.LOW_INV_PO_RAISED
2960
                order.statusDescription = 'In Process'
2961
                order.purchase_order_id = purchaseOrderId
2962
                itemIdQuantityMap[lineitem.item_id] -= lineitem.quantity
4434 mandeep.dh 2963
 
2819 chandransh 2964
    session.commit()
2965
 
3451 chandransh 2966
def update_weight(order_id, weight):
3469 chandransh 2967
    '''
2968
    Update the weight of order
2969
    '''
3451 chandransh 2970
    order = get_order(order_id)
2971
    order.total_weight = weight
3469 chandransh 2972
    lineitem = order.lineitems[0]
2973
    lineitem.total_weight = weight
2974
    lineitem.unit_weight = weight
3451 chandransh 2975
 
3469 chandransh 2976
    session.commit()
2977
    return order
2978
 
2979
def change_product(order_id, item_id):
2980
    '''
2981
    Ship a product of a different color to the customer.
2982
    '''
2983
    order = get_order(order_id)
4662 rajveer 2984
    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]:
3469 chandransh 2985
        raise TransactionServiceException(120, "This order has already been processed. Please seek help from engineering.")
2986
 
2987
    lineitem = order.lineitems[0]
3451 chandransh 2988
 
3469 chandransh 2989
    catalog_client = CatalogClient().get_client()
2990
 
2991
    old_item = catalog_client.getItem(lineitem.item_id)
2992
    item = catalog_client.getItem(item_id)
2993
    if old_item.catalogItemId != item.catalogItemId:
2994
        raise TransactionServiceException(121, "You can't ship a different item. You can only ship the same item in a different color.")
2995
 
5944 mandeep.dh 2996
    inventoryClient = InventoryClient().get_client()
5966 rajveer 2997
    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)
5110 mandeep.dh 2998
    __update_inventory_reservation(order)
3469 chandransh 2999
    #TODO: Check that this new item has the same price
3000
 
3001
    lineitem.item_id = item_id
3002
    lineitem.color = item.color
3003
 
3451 chandransh 3004
    session.commit()
3469 chandransh 3005
 
3006
    order = get_order(order_id)
3451 chandransh 3007
    return order
3469 chandransh 3008
 
3009
def change_warehouse(order_id, warehouse_id):
3010
    '''
3011
    Update the warehouse which will be used to fulfil this order.
3012
    '''
3013
    order = get_order(order_id)
6019 rajveer 3014
    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]:
3469 chandransh 3015
        raise TransactionServiceException(117, "This order has already been processed. Please seek help from engineering.")
3016
 
3017
    if warehouse_id == order.warehouse_id:
3018
        raise TransactionServiceException(118, "You have selected the current warehouse again. Nothing to do")
3019
 
3020
    lineitem = order.lineitems[0]
3021
    catalog_client = CatalogClient().get_client()
5944 mandeep.dh 3022
    inventoryClient = InventoryClient().get_client()
3469 chandransh 3023
    try:
5944 mandeep.dh 3024
        warehouse = inventoryClient.getWarehouse(warehouse_id)
3469 chandransh 3025
    except:
3026
        raise TransactionServiceException(119, "No warehouse with id" + str(warehouse_id))
5110 mandeep.dh 3027
 
6870 rajveer 3028
    if not warehouse.billingWarehouseId:
5147 mandeep.dh 3029
        raise TransactionServiceException(119, "Shifting of warehouse allowed to warehouse with billing support only")
5110 mandeep.dh 3030
 
5620 mandeep.dh 3031
    # If One gives a billing warehouse for warehouse shift, we should assign order to the GOOD warehouse
3032
    # present within it with maximum availability
3033
    if warehouse.id == warehouse.billingWarehouseId:
5944 mandeep.dh 3034
        warehouses = inventoryClient.getWarehouses(None, InventoryType.GOOD, 0, 0, warehouse.id)
5147 mandeep.dh 3035
        if warehouses:
5944 mandeep.dh 3036
            itemInventory = inventoryClient.getItemInventoryByItemId(lineitem.item_id)
5147 mandeep.dh 3037
            warehouse = warehouses[0]
3038
            maxAvailability = 0
3039
            for goodWarehouse in warehouses:
3040
                if itemInventory.availability.has_key(goodWarehouse.id) and maxAvailability < itemInventory.availability[goodWarehouse.id]:
3041
                    warehouse = goodWarehouse
3042
                    maxAvailability = itemInventory.availability[goodWarehouse.id]
3043
 
3044
            # Use preferred vendor's warehouse if not available anywhere
3045
            if not maxAvailability:
3046
                item = catalog_client.getItem(lineitem.item_id)
3047
                if item.preferredVendor:
3048
                    for goodWarehouse in warehouses:
3049
                        if goodWarehouse.vendor.id == item.preferredVendor:
3050
                            warehouse = goodWarehouse
3051
        else:
3052
            raise TransactionServiceException(119, "Shifting of warehouse allowed to GOOD inventory type warehouse with billing support")
3053
 
6007 rajveer 3054
    inventoryClient.reserveItemInWarehouse(lineitem.item_id, warehouse.id, sourceId, order.id, to_java_date(order.created_timestamp), to_java_date(order.promised_shipping_time), lineitem.quantity)
5110 mandeep.dh 3055
    __update_inventory_reservation(order)
6789 rajveer 3056
    if order.status == OrderStatus.ACCEPTED:
3057
        __update_transfer_price(order, warehouse.id)
5110 mandeep.dh 3058
    order.warehouse_id = warehouse.billingWarehouseId
5147 mandeep.dh 3059
    order.fulfilmentWarehouseId = warehouse.id
3469 chandransh 3060
    session.commit()
3061
    return order
3553 chandransh 3062
 
6789 rajveer 3063
def __update_transfer_price(order, warehouse_id):
3064
    lineitem = order.lineitems[0]
3065
    inventory_client = InventoryClient().get_client()
3066
    warehouse = inventory_client.getWarehouse(warehouse_id)
3067
    item_pricing = inventory_client.getItemPricing(lineitem.item_id, warehouse.vendor.id)
3068
    lineitem.transfer_price = item_pricing.transferPrice
3069
    lineitem.nlc = item_pricing.nlc
3070
 
4647 rajveer 3071
def add_delay_reason(order_id, reason, further_delay, delayReasonText):
3553 chandransh 3072
    '''
3994 chandransh 3073
    Adds a delay reason to the order and updates the expected delivery time.
3553 chandransh 3074
    '''
3075
    order = get_order(order_id)
3076
    try:
3581 chandransh 3077
        order.delay_reason = DelayReason._VALUES_TO_NAMES[reason]
4647 rajveer 3078
        order.delayReasonText = delayReasonText
4009 chandransh 3079
        actual_delivery_delay = adjust_delivery_time(order.expected_delivery_time, further_delay)
3080
        order.expected_delivery_time = order.expected_delivery_time + datetime.timedelta(days=actual_delivery_delay)
4102 chandransh 3081
 
4842 rajveer 3082
        actual_shipping_delay = adjust_delivery_time(order.expected_shipping_time, further_delay)
3083
        order.expected_shipping_time = order.expected_shipping_time + datetime.timedelta(days=actual_shipping_delay)
4102 chandransh 3084
 
6726 rajveer 3085
        order.courier_delivery_time = order.courier_delivery_time + datetime.timedelta(days=adjust_delivery_time(order.courier_delivery_time, further_delay))
3086
 
3553 chandransh 3087
        session.commit()
4008 mandeep.dh 3088
 
3089
        try:
3090
            transaction_requiring_extra_processing = TransactionRequiringExtraProcessing()
3091
            transaction_requiring_extra_processing.category = 'DELAYED_DELIVERY'
3092
            transaction_requiring_extra_processing.transaction_id = order.transaction_id
3093
            session.commit()
3094
        except Exception as e:
4065 mandeep.dh 3095
            print 'Could not persist transaction id: ' + str(order.transaction_id) + ' for further processing due to: ' + str(e)
4008 mandeep.dh 3096
 
3553 chandransh 3097
        return True
3098
    except:
3994 chandransh 3099
        print sys.exc_info()[0]
3553 chandransh 3100
        return False
3956 chandransh 3101
 
3102
def reconcile_cod_collection(collected_amount_map, xferBy, xferTxnId, xferDate):
3103
    unprocessed_awbs = {}
3104
    for awb, amount in collected_amount_map.iteritems():
3105
        try:
3106
            order = Order.query.filter_by(airwaybill_no=awb).one()
3107
        except NoResultFound:
3108
            unprocessed_awbs[awb] = "No order was found for the given AWB: " + awb
3109
            continue
3110
        except MultipleResultsFound:
3111
            unprocessed_awbs[awb] = "Multiple orders were found for the given AWB:" + awb
3112
            continue
3113
 
3114
        if order.cod_reconciliation_timestamp:
3115
            #This order has been processed already! This may be a re-run. Let's allow other orders to be processed.
3116
            continue
3117
 
3118
        if order.status < OrderStatus.DELIVERY_SUCCESS:
3119
            #Order has not been delivered yet. No way we can receive the payment.
3120
            unprocessed_awbs[awb] = "Payment has been received for order: " + str(order.id) + " before delivery reconciliation"
3121
            continue
3122
 
4252 rajveer 3123
        ##As per ticket #743 if amount difference less than 0.5 we should reconcile
6318 rajveer 3124
        if abs(amount - (order.total_amount - order.gvAmount)) > 0.5:
3956 chandransh 3125
            #Received amount is less than or more than the order amount. Mustn't let the user proceed.
6318 rajveer 3126
            unprocessed_awbs[awb] = "Payment of Rs. " + str(amount) + " has been received against the total value of Rs. " + str(order.total_amount-order.gvAmount) + " for order: " + str(order.id)
3956 chandransh 3127
            continue
3128
 
3129
        try:
3130
            payment_client = PaymentClient().get_client()
3131
            payment_client.partiallyCapturePayment(order.transaction.id, amount, xferBy, xferTxnId, xferDate)
3132
        except Exception:
3133
            unprocessed_awbs[awb] = "We were unable to partially capture payment for order id " + str(order.id) + ", AWB: " + awb
3134
            continue
3135
 
3136
        #Payment has been recorded now. We can update the order peacefully.
3137
        order.cod_reconciliation_timestamp = datetime.datetime.now()
3138
        session.commit()
3469 chandransh 3139
 
3956 chandransh 3140
    return unprocessed_awbs
4008 mandeep.dh 3141
 
3142
def get_transactions_requiring_extra_processing(category):
4065 mandeep.dh 3143
    """
3144
    Returns the list of transaction ids that require some extra processing and
3145
    which belong to a particular category. This is currently used by CRM
3146
    application. If no such transaction ids are present, it returns an empty list.
3147
    """
3148
    query = TransactionRequiringExtraProcessing.query
4008 mandeep.dh 3149
 
4065 mandeep.dh 3150
    if category is not None:
3151
        query = query.filter_by(category = ExtraTransactionProcessingType._VALUES_TO_NAMES.get(category))
4008 mandeep.dh 3152
 
4065 mandeep.dh 3153
    return [a.transaction_id for a in query.all()]
4008 mandeep.dh 3154
 
3155
def mark_transaction_as_processed(transactionId, category):
4065 mandeep.dh 3156
    """
3157
    Marks a particular transaction as processed for a particular cateogory.
3158
    It essentially deletes the transaction id record for a particular
3159
    processing type category (if present) from DB.
3160
    This is currently used by CRM application.
3161
    """
4008 mandeep.dh 3162
    TransactionRequiringExtraProcessing.query.filter_by(transaction_id = transactionId).filter_by(category = ExtraTransactionProcessingType._VALUES_TO_NAMES.get(category)).delete()
3163
    session.commit()
3164
 
4018 chandransh 3165
def get_item_wise_risky_orders_count():
3166
    """
3167
    Returns a map containing the number of risky orders keyed by item id. A risky order
3168
    is defined as one whose shipping date is about to expire.
3169
    """
3170
    item_wise_risky_orders_count = {}
4019 chandransh 3171
    shipping_cutoff_time = (datetime.datetime.now() + datetime.timedelta(days = 1)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
4018 chandransh 3172
    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()
3173
    for order in orders:
3174
        for lineitem in order.lineitems:
3175
            quantity = lineitem.quantity
3176
            if item_wise_risky_orders_count.has_key(lineitem.item_id):
3177
                quantity = quantity + item_wise_risky_orders_count[lineitem.item_id]
3178
 
3179
            item_wise_risky_orders_count[lineitem.item_id] = quantity
3180
    return item_wise_risky_orders_count
3181
 
4324 mandeep.dh 3182
def update_shipment_address(order_id, address_id):
3183
    """
3184
    Updates shipment address of an order. Delivery and shipping date estimates
3185
    etc. are also updated here.
3186
 
3187
    Throws TransactionServiceException in case address change is not
3188
    possible due to certain reasons such as new pincode in address is
3189
    not serviceable etc.
3190
 
3191
    Parameters:
3192
     - orderId
3193
     - addressId
3194
    """
3195
    user_client = UserClient().get_client()
3196
    address     = user_client.getAddressById(address_id)
3197
    order       = get_order(order_id)
3198
 
4630 mandeep.dh 3199
    type = DeliveryType.PREPAID
3200
    if order.cod:
3201
        type = DeliveryType.COD
3202
 
4324 mandeep.dh 3203
    logistics_client = LogisticsClient().get_client()
5886 mandeep.dh 3204
    logistics_info = logistics_client.getLogisticsEstimation(order.lineitems[0].item_id, address.pin, type)
4324 mandeep.dh 3205
 
3206
    # Check for new estimate. Raise exception if new address is not serviceable
3207
    if logistics_info.deliveryTime == -1:
3208
        raise TransactionServiceException(1, 'Location not serviceable')
3209
 
3210
    # COD services are not available everywhere
3211
    if order.cod:
4868 rajveer 3212
        if not logistics_info.codAllowed:
4324 mandeep.dh 3213
            raise TransactionServiceException(2, 'COD service not available')
3214
 
5593 mandeep.dh 3215
    if logistics_info.providerId != order.logistics_provider_id:
5887 mandeep.dh 3216
        logistics_info = logistics_client.getLogisticsInfo(address.pin, order.lineitems[0].item_id, type, PickUpType.COURIER)
5593 mandeep.dh 3217
        order.tracking_id = logistics_info.airway_billno
3218
        order.airwaybill_no = logistics_info.airway_billno
3219
        order.logistics_provider_id = logistics_info.providerId
3220
 
6525 rajveer 3221
    order.otg = logistics_info.otgAvailable
4324 mandeep.dh 3222
    current_time = datetime.datetime.now()
3223
    logistics_info.deliveryTime = adjust_delivery_time(current_time, logistics_info.deliveryTime)
3224
    logistics_info.shippingTime = adjust_delivery_time(current_time, logistics_info.shippingTime)
6726 rajveer 3225
    logistics_info.deliveryDelay = adjust_delivery_time(current_time, (logistics_info.shippingTime+logistics_info.deliveryDelay))
4324 mandeep.dh 3226
 
3227
    order.customer_name         = address.name
3228
    order.customer_pincode      = address.pin
3229
    order.customer_address1     = address.line1
3230
    order.customer_address2     = address.line2
3231
    order.customer_city         = address.city
3232
    order.customer_state        = address.state
3233
    order.customer_mobilenumber = address.phone
3234
 
3235
    if order.cod:
3236
        order.expected_shipping_time = (current_time + datetime.timedelta(days=logistics_info.shippingTime)).replace(hour=COD_SHIPPING_CUTOFF_TIME, minute=0, second=0)
6726 rajveer 3237
        order.expected_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryTime)).replace(hour=COD_SHIPPING_CUTOFF_TIME, minute=0, second=0)
3238
        order.courier_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryDelay)).replace(hour=COD_SHIPPING_CUTOFF_TIME, minute=0, second=0)
4324 mandeep.dh 3239
    else:
3240
        order.expected_shipping_time = (current_time + datetime.timedelta(days=logistics_info.shippingTime)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
6726 rajveer 3241
        order.expected_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryTime)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
3242
        order.courier_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryDelay)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
4324 mandeep.dh 3243
 
3244
    order.promised_shipping_time = order.expected_shipping_time
3245
    order.promised_delivery_time = order.expected_delivery_time 
3246
 
3247
    session.commit()
3248
 
4247 rajveer 3249
def mark_order_cancellation_request_received(orderId):
3250
    """
3251
    Mark order as cancellation request received. If customer sends request of cancellation of
3252
    a particular order, this method will be called. It will just change status of the order
3253
    depending on its current status. It also records the previous status, so that we can move
3254
    back to that status if cancellation request is denied.
3255
 
3256
    Parameters:
3257
     - orderId
3258
    """
4662 rajveer 3259
    status_transition = {OrderStatus.COD_VERIFICATION_PENDING : OrderStatus.CANCEL_REQUEST_RECEIVED,
4247 rajveer 3260
             OrderStatus.SUBMITTED_FOR_PROCESSING : OrderStatus.CANCEL_REQUEST_RECEIVED,
3261
             OrderStatus.INVENTORY_LOW : OrderStatus.CANCEL_REQUEST_RECEIVED,
4306 rajveer 3262
             OrderStatus.LOW_INV_PO_RAISED : OrderStatus.CANCEL_REQUEST_RECEIVED,
3263
             OrderStatus.LOW_INV_REVERSAL_IN_PROCESS : OrderStatus.CANCEL_REQUEST_RECEIVED,
3264
             OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT : OrderStatus.CANCEL_REQUEST_RECEIVED,
4247 rajveer 3265
             OrderStatus.ACCEPTED : OrderStatus.CANCEL_REQUEST_RECEIVED,
3266
             OrderStatus.BILLED : OrderStatus.CANCEL_REQUEST_RECEIVED,
3267
             OrderStatus.PAYMENT_FLAGGED : OrderStatus.CANCEL_REQUEST_RECEIVED
3268
             }
4662 rajveer 3269
 
3270
    order = get_order(orderId)
4247 rajveer 3271
    if order.status not in status_transition.keys():
3272
        raise TransactionServiceException(114, "This order can't be considered for cancellation")
3273
 
4662 rajveer 3274
 
4247 rajveer 3275
    order.previousStatus = order.status
3276
    order.status = OrderStatus.CANCEL_REQUEST_RECEIVED
3277
    order.statusDescription = "Cancellation request received from user"
3278
    session.commit()
3279
 
4662 rajveer 3280
def mark_order_as_lost_in_transit(orderId):
3281
    """
3282
    Parameters:
3283
     - orderId
3284
    """
3285
    order = get_order(orderId)
4910 phani.kuma 3286
    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]:
4662 rajveer 3287
        raise TransactionServiceException(115, "This order can't be marked as lost in transit")
3288
    order.status = OrderStatus.LOST_IN_TRANSIT
3289
    order.statusDescription = "Lost in Transit"
3290
    session.commit()
3291
 
4258 rajveer 3292
def mark_transaction_as_payment_flag_removed(transactionId):
4247 rajveer 3293
    """
4258 rajveer 3294
    If we and/or payment gateway has decided to accept the payment, this method needs to be called.
3295
    Changed transaction and all orders status to payment accepted.
4247 rajveer 3296
 
3297
    Parameters:
4258 rajveer 3298
     - transactionId
4247 rajveer 3299
    """
4258 rajveer 3300
    transaction = get_transaction(transactionId)
3301
    transaction.status = TransactionStatus.AUTHORIZED
3302
    for order in transaction.orders:
3303
        order.status = OrderStatus.SUBMITTED_FOR_PROCESSING
3304
        order.statusDescription = "Submitted to warehouse"
4247 rajveer 3305
    session.commit()
3306
 
4259 anupam.sin 3307
def refund_transaction(transactionId, refundedBy, reason):
3308
    """
3309
    This method is called when a flagged payment is deemed unserviceable and the corresponding orders
3310
    need to be cancelled
3311
 
3312
    Parameters:
3313
     - transactionId
3314
    """
3315
    transaction = get_transaction(transactionId)
3316
    transaction.status = TransactionStatus.FAILED
3317
    for order in transaction.orders:
3318
        refund_order(order.id, refundedBy, reason)
3319
    session.commit()
3320
 
4247 rajveer 3321
def mark_order_cancellation_request_denied(orderId):
3322
    """
4283 anupam.sin 3323
    If we decide to not to cancel order, we will move the order to previous status.
4247 rajveer 3324
 
3325
    Parameters:
3326
     - orderId
3327
    """
3328
    order = get_order(orderId)
3329
    order.status = order.previousStatus
3330
    order.previousStatus = None
3331
    order.statusDescription = "Cancellation request denied"
3332
    session.commit()
3333
 
3334
def mark_order_cancellation_request_confirmed(orderId):
3335
    """
3336
    If we decide to to cancel order, CRM will call this method to move the status of order to
3337
    cancellation request confirmed. After this OM will be able to cancel the order.
3338
 
3339
    Parameters:
3340
     - orderId
3341
    """
3342
    order = get_order(orderId)
3343
    order.status = OrderStatus.CANCEL_REQUEST_CONFIRMED
3344
    order.statusDescription = "Cancellation request confirmed"
3345
    session.commit()
3346
 
4285 rajveer 3347
def accept_orders_for_item_id(itemId, inventory):
3348
    """
3349
    Marks the orders as ACCEPTED for the given itemId and inventory. It also updates the accepted timestamp. If the
3350
    given order is not a COD order, it also captures the payment if the same has not been captured.
3351
 
3352
    Parameters:
3353
     - itemId
3354
     - inventory
3355
    """
6782 rajveer 3356
    orders = Order.query.filter(Order.warehouse_id == 9).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.expected_shipping_time).all()
4285 rajveer 3357
    for order in orders:
4301 rajveer 3358
        if inventory > 0:
3359
            lineitem = order.lineitems[0]
3360
            if itemId == lineitem.item_id:
3361
                try:
3362
                    accept_order(order.id)
3363
                    inventory = inventory - lineitem.quantity
3364
                except:
3365
                    logging.info("Unable to accept the order")
3366
        else:
3367
            order_outofstock(order.id)
4285 rajveer 3368
    return
3369
 
6864 rajveer 3370
def move_orders_to_correct_warehouse():
3371
    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()
3372
    logistics_client = LogisticsClient().get_client()
3373
    for order in orders:
3374
        lineitem = order.lineitems[0]
6870 rajveer 3375
        logistics_info = logistics_client.getLogisticsInfo(order.customer_pincode, lineitem.item_id, order.cod, PickUpType.COURIER)
6864 rajveer 3376
        if order.fulfilmentWarehouseId != logistics_info.fulfilmentWarehouseId:
6870 rajveer 3377
            try:
3378
                print "++++" + str(order.id) + "=" + str(order.fulfilmentWarehouseId) + "->"+ str(logistics_info.fulfilmentWarehouseId)
3379
                change_warehouse(order.id, logistics_info.fulfilmentWarehouseId)
3380
            except:
3381
                print "++++" + str(order.id)
6864 rajveer 3382
 
4607 rajveer 3383
def get_slipped_sipping_date_orders():
4662 rajveer 3384
    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()
4709 rajveer 3385
 
3386
def get_cancelled_orders(cancelDateFrom, cancelDateTo):
3387
    return Order.query.filter(Order.status == OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY).filter(Order.refund_timestamp >= cancelDateFrom).filter(Order.refund_timestamp <= cancelDateTo).all()
4607 rajveer 3388
 
4369 rajveer 3389
def mark_orders_as_po_raised(vendorId, itemId, quantity, estimate, isReminder):
3390
    if isReminder:
3391
        statuses = tuple([OrderStatus.LOW_INV_PO_RAISED_TIMEOUT, OrderStatus.LOW_INV_REVERSAL_TIMEOUT])
3392
    else:
3393
        statuses = tuple([OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW])
3394
 
3395
    orders = Order.query.filter(Order.status.in_(statuses)).order_by(Order.expected_shipping_time).all()
4303 rajveer 3396
    for order in orders:
3397
        lineitem = order.lineitems[0]
3398
        if quantity >= lineitem.quantity and itemId == lineitem.item_id:
3399
            if estimate > 0:
3400
                add_delay_reason(order.id, DelayReason.OTHERS, estimate)
3401
            order.status = OrderStatus.LOW_INV_PO_RAISED
4362 rajveer 3402
            order.statusDescription = "PO Raised"
4303 rajveer 3403
            quantity = quantity - lineitem.quantity
3404
            store_inventory_action(order, itemId, HotspotAction.PO_RAISED, estimate, lineitem.quantity)
3405
            session.commit()
3406
 
4369 rajveer 3407
def mark_orders_as_reversal_initiated(vendorId, itemId, quantity, estimate, isReminder):
3408
    if isReminder:
3409
        statuses = tuple([OrderStatus.LOW_INV_PO_RAISED_TIMEOUT, OrderStatus.LOW_INV_REVERSAL_TIMEOUT])
3410
    else:
3411
        statuses = tuple([OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW])
3412
    orders = Order.query.filter(Order.status.in_(statuses)).order_by(Order.expected_shipping_time).all()
4303 rajveer 3413
    for order in orders:
3414
        lineitem = order.lineitems[0]
3415
        if quantity >= lineitem.quantity and itemId == lineitem.item_id:
3416
            if estimate > 0:
3417
                add_delay_reason(order.id, DelayReason.OTHERS, estimate)
3418
            order.status = OrderStatus.LOW_INV_REVERSAL_IN_PROCESS
4362 rajveer 3419
            order.statusDescription = "Reversal Initiated"
4303 rajveer 3420
            quantity = quantity - lineitem.quantity
3421
            store_inventory_action(order, itemId, HotspotAction.REVERSAL_INITIATED, estimate, lineitem.quantity)
3422
            session.commit()
3423
 
4369 rajveer 3424
def mark_orders_as_not_available(vendorId, itemId, quantity, estimate, isReminder):
3425
    if isReminder:
3426
        statuses = tuple([OrderStatus.LOW_INV_PO_RAISED_TIMEOUT, OrderStatus.LOW_INV_REVERSAL_TIMEOUT])
3427
    else:
3428
        statuses = tuple([OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW])
3429
 
3430
    orders = Order.query.filter(Order.status.in_(statuses)).order_by(Order.expected_shipping_time).all()
4303 rajveer 3431
    for order in orders:
3432
        lineitem = order.lineitems[0]
3433
        if quantity >= lineitem.quantity and itemId == lineitem.item_id:
3434
            order.status = OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT
4362 rajveer 3435
            order.statusDescription = "Not Available"
4303 rajveer 3436
            quantity = quantity - lineitem.quantity
3437
            store_inventory_action(order, itemId, HotspotAction.NOT_AVAILABLE, estimate, lineitem.quantity)
3438
            session.commit()
3439
 
3440
def store_inventory_action(order, itemId, hotspotAction, estimate, quantity):
4369 rajveer 3441
    orderInv = OrderInventory.get_by(order_id=order.id)
3442
    if not orderInv:
3443
        orderInv = OrderInventory()
3444
        orderInv.order = order
4303 rajveer 3445
    orderInv.hotspotAction = hotspotAction  
3446
    orderInv.estimate = estimate
3447
    orderInv.itemId = itemId
3448
    orderInv.timestamp = datetime.datetime.now()
3449
    orderInv.quantity = quantity
3450
 
4556 mandeep.dh 3451
'''    
4369 rajveer 3452
def mark_orders_as_timeout(vendorId):
3453
    ret_timeouts = {}
3454
    orderInvs = OrderInventory.query.all()
3455
    for orderInv in orderInvs:
3456
        if orderInv.timestamp +  timedelta(days=orderInv.estimate) < datetime.datetime.now():
3457
            if not ret_timeouts.has_key(orderInv.itemId):
3458
                timeout = TimeoutSummary()
3459
                ret_timeouts[orderInv.itemId] = timeout
3460
            else:
3461
                timeout = ret_timeouts.get(orderInv.itemId)
3462
            if orderInv.hotspotAction == HotspotAction.PO_RAISED and orderInv.order.status == OrderStatus.LOW_INV_PO_RAISED:
3463
                if timeout.poRaised:
3464
                    timeout.poRaised += 1
3465
                else:
3466
                    timeout.poRaised = 1
3467
 
3468
                if timeout.poEstimate:
3469
                    timeout.poEstimate += orderInv.estimate
3470
                else:
3471
                    timeout.poEstimate = orderInv.estimate
3472
                orderInv.order.status = OrderStatus.LOW_INV_PO_RAISED_TIMEOUT
3473
                orderInv.order.statusDescription = "PO Raised Timeout"
3474
            elif orderInv.hotspotAction == HotspotAction.REVERSAL_INITIATED and orderInv.order.status == OrderStatus.LOW_INV_REVERSAL_IN_PROCESS:
3475
                if timeout.reversalInitiated:
3476
                    timeout.reversalInitiated += 1
3477
                else:
3478
                    timeout.reversalInitiated = 1
3479
 
3480
                if timeout.reversalEstimate:
3481
                    timeout.reversalEstimate += orderInv.estimate
3482
                else:
3483
                    timeout.reversalEstimate = orderInv.estimate
3484
                orderInv.order.status = OrderStatus.LOW_INV_REVERSAL_TIMEOUT
3485
                orderInv.order.statusDescription = "Reversal Initiated Timeout"
3486
            else:
3487
                orderInv.delete()
3488
    session.commit()
3489
    return ret_timeouts
4556 mandeep.dh 3490
'''
3491
 
3492
 
3493
def mark_orders_as_timeout(vendorId):
3494
    ret_timeouts = {}
3495
    orderInvs = OrderInventory.query.all()
3496
    for orderInv in orderInvs:
3497
        if not ret_timeouts.has_key(orderInv.itemId):
3498
            timeout = TimeoutSummary()
3499
            ret_timeouts[orderInv.itemId] = timeout
3500
        else:
3501
            timeout = ret_timeouts.get(orderInv.itemId)
3502
        if orderInv.hotspotAction == HotspotAction.PO_RAISED and orderInv.order.status == OrderStatus.LOW_INV_PO_RAISED:
3503
            if timeout.poRaised:
3504
                timeout.poRaised += 1
3505
            else:
3506
                timeout.poRaised = 1
3507
 
3508
            if timeout.poEstimate:
3509
                timeout.poEstimate = max(orderInv.estimate, timeout.poEstimate)
3510
            else:
3511
                timeout.poEstimate = orderInv.estimate
3512
        elif orderInv.hotspotAction == HotspotAction.REVERSAL_INITIATED and orderInv.order.status == OrderStatus.LOW_INV_REVERSAL_IN_PROCESS:
3513
            if timeout.reversalInitiated:
3514
                timeout.reversalInitiated += 1
3515
            else:
3516
                timeout.reversalInitiated = 1
3517
 
3518
            if timeout.reversalEstimate:
3519
                timeout.reversalEstimate = max(orderInv.estimate, timeout.reversalEstimate)
3520
            else:
3521
                timeout.reversalEstimate = orderInv.estimate
3522
        orderInv.order.status = OrderStatus.INVENTORY_LOW
3523
        orderInv.order.statusDescription = "Low Inventory"
3524
        orderInv.delete()
3525
    session.commit()
3526
    return ret_timeouts
3527
 
4386 anupam.sin 3528
def get_order_for_awb(awb):
3529
    order = Order.get_by(airwaybill_no=awb)
3530
    if not order:
3531
        raise TransactionServiceException(108, "no such order")
3532
 
3533
    return order
4369 rajveer 3534
 
4910 phani.kuma 3535
def get_orders_for_provider_for_status(provider_id, order_status_list):
3536
    if not provider_id or not order_status_list:
4506 phani.kuma 3537
        raise TransactionServiceException(101, "bad provider id or order status")
4910 phani.kuma 3538
    doa_provider = False
3539
    for order_status in order_status_list:
3540
        if order_status in [OrderStatus.DOA_PICKUP_CONFIRMED, OrderStatus.RET_PICKUP_CONFIRMED]:
3541
            doa_provider = True
3542
    if doa_provider:
3543
        query = Order.query.filter_by(doa_logistics_provider_id = provider_id).filter(Order.status.in_(order_status_list))
4815 phani.kuma 3544
    else:
4910 phani.kuma 3545
        query = Order.query.filter_by(logistics_provider_id = provider_id).filter(Order.status.in_(order_status_list))
4506 phani.kuma 3546
    return query.all()
4386 anupam.sin 3547
 
4600 varun.gupt 3548
def get_billed_orders_for_vendor(vendor_id, billing_date_from, billing_date_to):
5368 mandeep.dh 3549
    query = Order.query.filter(Order.status != OrderStatus.PAYMENT_PENDING)
3550
 
3551
    if vendor_id:
3552
        query = query.filter_by(vendorId = vendor_id)
3553
 
4600 varun.gupt 3554
    if billing_date_from:
3555
        query = query.filter(Order.billing_timestamp >= billing_date_from)
5368 mandeep.dh 3556
 
4600 varun.gupt 3557
    if billing_date_to:
3558
        query = query.filter(Order.billing_timestamp <= billing_date_to)
5368 mandeep.dh 3559
 
4600 varun.gupt 3560
    return query.all()
3561
 
5481 phani.kuma 3562
def get_billed_orders(vendor_id, onlyVendorNotPaid, billing_date_from, billing_date_to):
5386 phani.kuma 3563
    query = Order.query.filter(Order.billing_timestamp != None)
5481 phani.kuma 3564
 
3565
    if onlyVendorNotPaid:
5488 phani.kuma 3566
        query = query.filter_by(vendor_paid = False)
5481 phani.kuma 3567
 
5386 phani.kuma 3568
    if vendor_id != -1:
3569
        query = query.filter_by(vendorId = vendor_id)
3570
 
5481 phani.kuma 3571
    if billing_date_from:
3572
        query = query.filter(Order.billing_timestamp >= billing_date_from)
3573
 
3574
    if billing_date_to:
3575
        query = query.filter(Order.billing_timestamp <= billing_date_to)
3576
 
4885 varun.gupt 3577
    return query.all()
4875 varun.gupt 3578
 
4600 varun.gupt 3579
def save_bluedart_settlements(map_awb_and_amount):
3580
    payment_client = PaymentClient().get_client()
3581
 
3582
    for awb, amount in map_awb_and_amount.iteritems():
3583
        order = Order.get_by(airwaybill_no = awb)
3584
 
3585
        payment = payment_client.getSuccessfulPaymentForTxnId(order.transaction_id)
3586
        settlement = PaymentSettlement()
3587
        settlement.paymentId = payment.paymentId
3588
        settlement.paymentGatewayId = payment.gatewayId
3589
        settlement.netCollection = amount
3590
        session.commit()
3591
 
4905 varun.gupt 3592
def save_payment_settlements(settlementDate, paymentGatewayId, referenceId, serviceTax, otherCharges, netCollection):
5386 phani.kuma 3593
    originalOrderId = None
3594
    if paymentGatewayId == 4:
3595
        cod_order = Order.get_by(id = referenceId)
3596
        if cod_order.originalOrderId:
3597
            originalOrderId = cod_order.originalOrderId
3598
        else:
3599
            originalOrderId = referenceId
4600 varun.gupt 3600
    settlement = PaymentSettlement()
3601
    settlement.settlementDate = settlementDate
3602
    settlement.paymentGatewayId = paymentGatewayId
5386 phani.kuma 3603
    if originalOrderId is not None:
3604
        settlement.originalOrderId = originalOrderId
4905 varun.gupt 3605
    settlement.referenceId = referenceId
4600 varun.gupt 3606
    settlement.serviceTax = serviceTax
3607
    settlement.otherCharges = otherCharges
3608
    settlement.netCollection = netCollection
3609
    session.commit()
3610
 
5386 phani.kuma 3611
def get_settlement_for_Prepaid(reference_id, is_refund = False):
3612
    query = PaymentSettlement.query.filter_by(referenceId = reference_id).filter(PaymentSettlement.paymentGatewayId != 4)
4600 varun.gupt 3613
 
5189 varun.gupt 3614
    if is_refund:
3615
        query = query.filter(PaymentSettlement.netCollection < 0)
3616
    else:
3617
        query = query.filter(PaymentSettlement.netCollection > 0)
3618
 
5386 phani.kuma 3619
    return query.first()
3620
 
3621
def get_settlement_for_Cod(orderId, is_refund = False):
3622
    query = PaymentSettlement.query.filter_by(originalOrderId = orderId)
5382 varun.gupt 3623
 
5386 phani.kuma 3624
    if is_refund:
3625
        query = query.filter(PaymentSettlement.netCollection < 0)
3626
    else:
3627
        query = query.filter(PaymentSettlement.netCollection > 0)
3628
 
5189 varun.gupt 3629
    return query.first()
4600 varun.gupt 3630
 
3631
def save_ebs_settlement_summary(settlement_id, settlement_date, transaction_date_from, transaction_date_to, amount):
5551 phani.kuma 3632
    summary = EBSSettlementSummary.query.filter_by(settlementId = settlement_id).first()
5481 phani.kuma 3633
    if summary is None:
3634
        summary = EBSSettlementSummary()
3635
        summary.settlementId = settlement_id
3636
        summary.settlementDate = settlement_date
3637
        summary.transactionDateFrom = transaction_date_from
3638
        summary.transactionDateTo = transaction_date_to
3639
        summary.amount = amount
3640
        summary.detailsUploaded = False
3641
        session.commit()
4600 varun.gupt 3642
 
3643
def get_ebs_settlement_summaries():
3644
    summaries = EBSSettlementSummary.query.filter_by(detailsUploaded = False).order_by(EBSSettlementSummary.transactionDateFrom).all()
3645
    summary_map = {}
3646
 
3647
    for summary in summaries:
3648
        transactionDateFrom = str(summary.transactionDateFrom.year) + '-' + str(summary.transactionDateFrom.month) + '-' + str(summary.transactionDateFrom.day)
3649
        transactionDateTo = str(summary.transactionDateTo.year) + '-' + str(summary.transactionDateTo.month) + '-' + str(summary.transactionDateTo.day)
3650
 
3651
        summary_map[summary.settlementId] = "%s to %s" %(transactionDateFrom, transactionDateTo)
3652
 
3653
    return summary_map
3654
 
3655
def get_ebs_settlement_date(settlement_id):
3656
    summary = EBSSettlementSummary.get_by(settlementId = settlement_id)
3657
 
3658
    if summary:
3659
        return summary.settlementDate
3660
 
3661
def mark_ebs_settlement_uploaded(settlement_id):
3662
    summary = EBSSettlementSummary.get_by(settlementId = settlement_id)
3663
 
3664
    if summary:
3665
        summary.detailsUploaded = True
3666
        session.commit()
4715 varun.gupt 3667
 
3668
def get_settlements_by_date(settlement_date_from, settlement_date_to, is_refund):
3669
    query = PaymentSettlement.query
4600 varun.gupt 3670
 
4715 varun.gupt 3671
    if settlement_date_from:
3672
        query = query.filter(PaymentSettlement.settlementDate >= settlement_date_from)
3673
 
3674
    if settlement_date_to:
3675
        query = query.filter(PaymentSettlement.settlementDate <= settlement_date_to)
3676
 
4749 varun.gupt 3677
    if is_refund is True:
3678
        query = query.filter(PaymentSettlement.netCollection < 0.0)
3679
    else:
3680
        query = query.filter(PaymentSettlement.netCollection > 0.0)
4715 varun.gupt 3681
 
4749 varun.gupt 3682
    return query.all()
4715 varun.gupt 3683
 
3684
def get_reshipped_order_ids(order_ids):
3685
    reshipped_order_ids = []
3686
    return [order.new_order_id for order in Order.query.filter(Order.new_order_id.in_(order_ids)).all()]
3687
 
4749 varun.gupt 3688
def get_shipping_confirmation_email_body(order):
3689
 
3690
    html = """
3691
<html>
3692
<body>
3693
<div>
3694
    <p>Dear Customer,</p>
3695
    <p>
4885 varun.gupt 3696
        We are pleased to inform that we have shipped the order: $order_id for your product $product_name on $shipping_datetime. 
5139 varun.gupt 3697
        The shipment will be delivered to you via $courier_name Courier Service vide AWB# $awb.
7198 amar.kumar 3698
 
4749 varun.gupt 3699
    </p>
3700
    <p>
6655 rajveer 3701
        Expected delivery date for your order is $expected_delivery_date.
6675 rajveer 3702
        <br/>
3703
        $otg_text
7198 amar.kumar 3704
        $freebie_text
6675 rajveer 3705
        <br/> 
6716 rajveer 3706
        The product can be delivered to you between business hours of 10am to 6pm.
3707
        You can Check the current shipment updates for your product online at <a href="www.saholic.com/myaccount">Open Orders</a>.
4749 varun.gupt 3708
    </p>
3709
    <p>
5573 amit.gupta 3710
        For scheduling the delivery of your product at some specific timings, we recommend you to contact the helpline for $courier_name with your complete AWB#.
4749 varun.gupt 3711
    </p>
5139 varun.gupt 3712
    <p>$courier_name: $courier_phone</p>
4749 varun.gupt 3713
    <p>
3714
        Warm Regards,<br />
6029 rajveer 3715
        $source_name Team
4749 varun.gupt 3716
    </p>
4750 varun.gupt 3717
</div>
4749 varun.gupt 3718
</body>
3719
</html>
3720
    """
5573 amit.gupta 3721
    logistics_providers = {1: {'name': 'BlueDart', 'phone': '011-66111234'}, 2: {'name': 'Aramex', 'phone': '0124- 39419900'}, 3: {'name': 'Delhivery', 'phone' : '0124- 4212200'}}
5139 varun.gupt 3722
    provider_name = logistics_providers[order.logistics_provider_id]['name']
3723
    provider_phone = logistics_providers[order.logistics_provider_id]['phone']
3724
 
5868 rajveer 3725
    lclient = LogisticsClient().get_client()
3726
    logistics_info = lclient.getLogisticsEstimation(order.lineitems[0].item_id, order.customer_pincode, DeliveryType.PREPAID)
4749 varun.gupt 3727
    dt = datetime.datetime.strptime(str(order.shipping_timestamp), "%Y-%m-%d %H:%M:%S")
4885 varun.gupt 3728
    shipping_date = dt.strftime("%A, %d %B %Y %I:%M%p")
6712 rajveer 3729
    product = str(order.lineitems[0])
5868 rajveer 3730
    new_expected_delivery_timestamp = datetime.datetime.now() + timedelta(adjust_delivery_time(datetime.datetime.now(), (logistics_info.deliveryTime - logistics_info.shippingTime)))
6728 rajveer 3731
    new_courier_delivery_time = datetime.datetime.now() + timedelta(adjust_delivery_time(datetime.datetime.now(), (logistics_info.deliveryTime - logistics_info.shippingTime - logistics_info.deliveryDelay)))
6666 rajveer 3732
    #update new expected timestamp
3733
    if order.cod:
6705 amar.kumar 3734
        new_expected_delivery_timestamp = new_expected_delivery_timestamp.replace(hour=COD_SHIPPING_CUTOFF_TIME, minute=0, second=0, microsecond=0)
6728 rajveer 3735
        order.courier_delivery_time = new_courier_delivery_time.replace(hour=COD_SHIPPING_CUTOFF_TIME, minute=0, second=0, microsecond=0)
6666 rajveer 3736
    else:
6705 amar.kumar 3737
        new_expected_delivery_timestamp = new_expected_delivery_timestamp.replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0, microsecond=0)
6728 rajveer 3738
        order.courier_delivery_time = new_courier_delivery_time.replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0, microsecond=0)
6666 rajveer 3739
    order.expected_delivery_time = new_expected_delivery_timestamp
3740
    session.commit()
3741
 
4885 varun.gupt 3742
    new_expected_delivery_date = new_expected_delivery_timestamp.strftime("%A, %d %B %Y")
6655 rajveer 3743
    otg_text = ""
3744
    if order.otg:
6662 rajveer 3745
        promised_delivery_date = order.promised_delivery_time.strftime("%A, %d %B %Y")
6655 rajveer 3746
        if new_expected_delivery_timestamp > order.promised_delivery_time:
6712 rajveer 3747
            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.'
6655 rajveer 3748
        elif new_expected_delivery_timestamp < order.promised_delivery_time:
6662 rajveer 3749
            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 + '.'
6655 rajveer 3750
        else:            
6662 rajveer 3751
            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 + '.'
7190 amar.kumar 3752
 
3753
    freebie_text = "<br/>"
3754
    if order.freebieItemId:
3755
        catalog_client = CatalogClient().get_client()
3756
        item = catalog_client.getItem(order.freebieItemId)
7198 amar.kumar 3757
        freebie_text = freebie_text = "We have also shipped you " + item.brand + " " + item.modelName + "" + item.modelNumber +" as promised<br/>"
7190 amar.kumar 3758
    else:
3759
        freebie_orderId = get_order_attribute_value(order.id, "freebieOrderId")
3760
        if freebie_orderId != "":
3761
            line_items = get_line_items_for_order(int(freebie_orderId))
7198 amar.kumar 3762
            freebie_order = get_order(int(freebie_orderId))
3763
            freebie_text = freebie_text + "We wish to inform you that your freebie item " +line_items[0].brand + " " + line_items[0].model_name + " " + line_items[0].model_number + " will be sent as a separate order with OrderId : " + freebie_orderId + " and is expected to be delivered on " + freebie_order.expected_delivery_time.strftime("%A, %d %B %Y")+ "<br/>"
3764
        else:
3765
            freebie_text = ""
6655 rajveer 3766
 
7190 amar.kumar 3767
    info = dict(order_id = order.id, product_name = product, 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)
4885 varun.gupt 3768
    return Template(html).substitute(info)
4749 varun.gupt 3769
 
5832 rajveer 3770
def enqueue_shipping_confirmation_email(order):
4915 varun.gupt 3771
    # Calling helper service on production
3772
    helperClient = HelperClient(host_key = "helper_service_server_host_prod").get_client()
5832 rajveer 3773
    try:
3774
        emailSubject = 'Shipping Details for Order ID: ' + str(order.id)
3775
        emailBody = get_shipping_confirmation_email_body(order)
6906 rajveer 3776
        helperClient.saveUserEmailForSending([order.customer_email], None, emailSubject, emailBody, str(order.id), 'ShippingConfirmation', [], [])
6687 rajveer 3777
 
5832 rajveer 3778
    except Exception as e:
3779
        print e
5139 varun.gupt 3780
 
4915 varun.gupt 3781
def get_order_distribution_by_status(start_date, end_date):
5067 varun.gupt 3782
    query = session.query(Order.status, func.count(Order.id)).group_by(Order.status)
3783
    query = query.filter(Order.created_timestamp >= start_date)
3784
    query = query.filter(Order.created_timestamp <= end_date)
3785
    return query.all()
4915 varun.gupt 3786
 
5067 varun.gupt 3787
def get_order_ids_for_status(status, start_datetime, end_datetime):
3788
    query = Order.query.filter(Order.status == status)
3789
    query = query.filter(Order.created_timestamp >= start_datetime)
3790
    query = query.filter(Order.created_timestamp <= end_datetime)
3791
    return query.all()
3792
 
5099 varun.gupt 3793
def update_orders_as_paid_to_vendor(order_id):
5139 varun.gupt 3794
    paid_order = Order.get_by(id = order_id)
5099 varun.gupt 3795
 
5139 varun.gupt 3796
    if paid_order.originalOrderId is None:
3797
        paid_order.vendor_paid = True
5099 varun.gupt 3798
        session.commit()
5139 varun.gupt 3799
 
3800
        for order in Order.query.filter(Order.originalOrderId == order_id).all():
3801
            order.vendor_paid = True
3802
            session.commit()
3803
    else:
5208 varun.gupt 3804
        original_order_id = paid_order.originalOrderId
5139 varun.gupt 3805
 
5208 varun.gupt 3806
        for order in Order.query.filter(Order.originalOrderId == original_order_id).all():
5139 varun.gupt 3807
            order.vendor_paid = True
3808
            session.commit()
3809
 
3810
        original_order = Order.get_by(id = original_order_id)
3811
        if original_order:  original_order.vendor_paid = True
3812
        session.commit()
5348 anupam.sin 3813
 
3814
def update_COD_agent(agentEmailId, orderId):
3815
    order = Order.get_by(id=orderId)
3816
    if not order:
3817
        raise TransactionServiceException(101, "No order found for the given order id" + str(orderId))
3818
    agent = CodVerificationAgent()
3819
    agent.orderId = orderId
3820
    agent.verificationAgent = agentEmailId
3821
    session.commit()
3822
 
5099 varun.gupt 3823
 
5386 phani.kuma 3824
def update_order_only_as_paid_to_vendor(order_id):
3825
    paid_order = Order.get_by(id = order_id)
3826
    if paid_order is None:
3827
        raise TransactionServiceException(116, "No order found for the given order id")
3828
    paid_order.vendor_paid = True
3829
    session.commit()
3830
 
5208 varun.gupt 3831
def get_refunded_orders_marked_paid():
3832
    orderStatusGroup = OrderStatusGroups()
3833
    return Order.query.filter(Order.vendor_paid == 1).filter(Order.status.in_(orderStatusGroup.refundedOrders)).all()
3834
 
5447 anupam.sin 3835
def get_all_verification_agents(minOrderId, maxOrderId):
3836
    return CodVerificationAgent.query.filter(CodVerificationAgent.orderId >= minOrderId).filter(CodVerificationAgent.orderId <= maxOrderId).all()
3837
 
5527 anupam.sin 3838
def get_all_attributes_for_order_id(orderId):
3839
    return Attribute.query.filter(Attribute.orderId == orderId).all()
3840
 
3841
def set_order_attribute_for_transaction(transactionId, t_attribute):
3842
    for order in Order.query.filter_by(transaction_id = transactionId).all():
3843
        attribute = Attribute()
3844
        attribute.orderId = order.id
3845
        attribute.name = t_attribute.name
3846
        attribute.value = t_attribute.value
3847
        session.commit()
5593 mandeep.dh 3848
 
5558 mandeep.dh 3849
def accept_order_for_item(itemId, quantity, fulfilmentWarehouseId, billingWarehouseId):
5944 mandeep.dh 3850
    inventoryClient = InventoryClient().get_client()
3851
    inventory = inventoryClient.getItemInventoryByItemId(itemId)
5684 mandeep.dh 3852
    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()
5558 mandeep.dh 3853
    for order in orders:
5593 mandeep.dh 3854
        lineitem = order.lineitems[0]
5558 mandeep.dh 3855
        if lineitem.item_id == itemId and lineitem.quantity <= quantity:
5944 mandeep.dh 3856
            warehouse = inventoryClient.getWarehouse(order.fulfilmentWarehouseId)
5684 mandeep.dh 3857
            if not warehouse.billingWarehouseId and warehouse.warehouseType == WarehouseType.THIRD_PARTY:
3858
                if (inventory.availability[fulfilmentWarehouseId] >= inventory.reserved[fulfilmentWarehouseId] + lineitem.quantity) and inventory.availability[order.fulfilmentWarehouseId] < inventory.reserved[order.fulfilmentWarehouseId]:
5966 rajveer 3859
                    inventoryClient.reduceReservationCount(itemId, order.fulfilmentWarehouseId, sourceId, order.id, lineitem.quantity)
3860
                    inventoryClient.reserveItemInWarehouse(itemId, fulfilmentWarehouseId, sourceId, order.id, to_java_date(order.created_timestamp), to_java_date(order.promised_shipping_time), lineitem.quantity)
5684 mandeep.dh 3861
                    order.fulfilmentWarehouseId = fulfilmentWarehouseId
5558 mandeep.dh 3862
                    quantity -= lineitem.quantity
5684 mandeep.dh 3863
                    session.commit()
5593 mandeep.dh 3864
                    if not quantity:
3865
                        break
5558 mandeep.dh 3866
 
6031 rajveer 3867
def get_recharge_order(rechargeOrderId):
6048 rajveer 3868
    return RechargeOrder.get_by(id = rechargeOrderId)
6031 rajveer 3869
 
3870
def get_recharge_orders(userId):
3871
    return RechargeOrder.query.filter_by(userId = userId).all()
3872
 
6279 rajveer 3873
def update_recharge_order_status(rechargeOrderId, rechargeOrderStatus, refundDate=None):
6031 rajveer 3874
    recharge_order = get_recharge_order(rechargeOrderId)
3875
    if rechargeOrderStatus == RechargeOrderStatus.PAYMENT_FAILED:
3876
        recharge_order.status = RechargeOrderStatus.PAYMENT_FAILED
3877
        session.commit()
3878
        return True
6214 rajveer 3879
 
3880
    if rechargeOrderStatus == RechargeOrderStatus.RECHARGE_FAILED:
3881
        recharge_order.status = RechargeOrderStatus.RECHARGE_FAILED
3882
        session.commit()
3883
        update_amount_in_wallet(recharge_order.userId, recharge_order.walletAmount, recharge_order.id)
6441 rajveer 3884
        update_amount_in_wallet(recharge_order.userId, recharge_order.totalAmount - recharge_order.walletAmount - recharge_order.couponAmount, recharge_order.id)
6214 rajveer 3885
        enqueue_recharge_info_email(recharge_order)
3886
        return True
3887
 
3888
    if rechargeOrderStatus == RechargeOrderStatus.RECHARGE_SUCCESSFUL:
3889
        recharge_order.status = RechargeOrderStatus.RECHARGE_SUCCESSFUL
6553 rajveer 3890
        recharge_order.invoiceNumber = get_next_invoice_number(OrderType.RECHARGE)
6214 rajveer 3891
        session.commit()
6285 rajveer 3892
        gvs = allocate_gift_voucher(recharge_order)
3893
        enqueue_recharge_info_email(recharge_order, gvs)
6214 rajveer 3894
        return True
3895
 
6279 rajveer 3896
    if rechargeOrderStatus == RechargeOrderStatus.RECHARGE_FAILED_REFUNDED:
3897
        recharge_order.status = RechargeOrderStatus.RECHARGE_FAILED_REFUNDED
3898
        order.responseTimestamp = refundDate
3899
        session.commit()
3900
        update_amount_in_wallet(recharge_order.userId, recharge_order.walletAmount, recharge_order.id)
6441 rajveer 3901
        update_amount_in_wallet(recharge_order.userId, recharge_order.totalAmount - recharge_order.walletAmount - recharge_order.couponAmount, recharge_order.id)
6279 rajveer 3902
        enqueue_recharge_info_email(recharge_order)
3903
        return True
3904
 
6031 rajveer 3905
    if rechargeOrderStatus == RechargeOrderStatus.PAYMENT_SUCCESSFUL:
6285 rajveer 3906
        gvs = {}
6206 rajveer 3907
        recharge_order.status = RechargeOrderStatus.PAYMENT_SUCCESSFUL
3908
        session.commit()
6031 rajveer 3909
        if recharge_order.walletAmount > 0:
3910
            wallet = get_user_wallet(recharge_order.userId)
3911
            if wallet and wallet.amount >= recharge_order.walletAmount:
3912
                update_amount_in_wallet(recharge_order.userId, -recharge_order.walletAmount, recharge_order.id)
3913
            else:
6441 rajveer 3914
                update_amount_in_wallet(recharge_order.userId, recharge_order.totalAmount - recharge_order.walletAmount - recharge_order.couponAmount, recharge_order.id)
6031 rajveer 3915
                raise TransactionServiceException(103, 'Wallet amount has already been used')
3916
 
6092 rajveer 3917
        try:
3918
            if activate_recharge_txn(recharge_order):
3919
                recharge_order.invoiceNumber = get_next_invoice_number(OrderType.RECHARGE)
3920
                session.commit()
6285 rajveer 3921
                gvs = allocate_gift_voucher(recharge_order)
6092 rajveer 3922
                return True
3923
            else:
3924
                update_amount_in_wallet(recharge_order.userId, recharge_order.walletAmount, recharge_order.id)
6441 rajveer 3925
                update_amount_in_wallet(recharge_order.userId, recharge_order.totalAmount - recharge_order.walletAmount - recharge_order.couponAmount, recharge_order.id)
6092 rajveer 3926
                session.commit()
3927
                return False
3928
        except:
3929
            transaction_requiring_extra_processing = TransactionRequiringExtraProcessing()
3930
            transaction_requiring_extra_processing.category = 'RECHARGE_UNKNOWN'
3931
            transaction_requiring_extra_processing.transaction_id = recharge_order.transaction_id
6031 rajveer 3932
            session.commit()
3933
            return False
6102 rajveer 3934
        finally:
6285 rajveer 3935
            enqueue_recharge_info_email(recharge_order, gvs)
6102 rajveer 3936
 
6031 rajveer 3937
 
6285 rajveer 3938
def allocate_gift_voucher(recharge_order):            
3939
    totalAmount = recharge_order.totalAmount
3940
    gvs = {}
6438 rajveer 3941
    return gvs
6330 rajveer 3942
    if totalAmount >= 100:
3943
        totalAmount=500 if totalAmount >= 500 else totalAmount
6285 rajveer 3944
        try:
3945
            pc = PromotionClient().get_client()
6330 rajveer 3946
            enddate = datetime.datetime.now() + datetime.timedelta(days=45)
6285 rajveer 3947
            while totalAmount > 0:
6330 rajveer 3948
                gvAmount = totalAmount if totalAmount <= 250 else 250
6285 rajveer 3949
                totalAmount = totalAmount - gvAmount
6561 amit.gupta 3950
                gv = pc.createCoupon(26, to_java_date(enddate), recharge_order.userEmailId, gvAmount, False, 1, None)
6285 rajveer 3951
                gvs[gv] = gvAmount  
3952
        except:
3953
            print "Not able to create gift voucher for user " + recharge_order.userEmailId
3954
    return gvs     
3955
 
6048 rajveer 3956
def activate_recharge_txn(recharge_order):
3957
    if isinstance(recharge_order, MobileRechargeOrder):
3958
        rechargeType = 'MTP'
3959
        deviceNumber = recharge_order.mobileNumber
3960
        strProviderCode = get_provider_code(recharge_order.mobileOperatorId)
6161 rajveer 3961
        plan = recharge_order.rechargePlan
6048 rajveer 3962
    if isinstance(recharge_order, DTHRechargeOrder):
3963
        rechargeType = 'RCH'
3964
        deviceNumber = recharge_order.dthAccountNumber
3965
        strProviderCode = get_provider_code(recharge_order.dthOperatorId)
6161 rajveer 3966
        plan = ''
7369 rajveer 3967
    retStatus, retCode, spiceTID, description, aggTID, providerTID = RechargeService.rechargeDevice(recharge_order.id, rechargeType, strProviderCode, deviceNumber, recharge_order.totalAmount, plan)
6231 rajveer 3968
    recharge_order.spiceTID = spiceTID
3969
    recharge_order.responseTimestamp = datetime.datetime.now()
3970
    recharge_order.description = description
3971
    session.commit()
6092 rajveer 3972
    if retCode == '00' and retStatus == 'S':
3973
        recharge_order.status = RechargeOrderStatus.RECHARGE_SUCCESSFUL
3974
        session.commit()
3975
        return True
6259 rajveer 3976
    elif retCode in ('STO', 'US', 'UP') and retStatus == 'S':
6231 rajveer 3977
        raise TransactionServiceException(111, "No response from operator within specified time")
6092 rajveer 3978
    else:
3979
        recharge_order.status = RechargeOrderStatus.RECHARGE_FAILED
6265 rajveer 3980
        if retCode in ('SVAI', 'SVIA', 'AI', 'IA', 'EAI', 'SVEAI'):
3981
            recharge_order.description = "Invalid Amount"
3982
        elif retCode in ('ECL', 'SVECL', 'SCL'):
3983
            recharge_order.description = "Customer Exceeded Daily Limit"
3984
        elif retCode in ('CI', 'ECI', 'ESP', 'SVCI', 'SVECI', 'SVESP', 'SV_ECI', 'SV ECI'):
6399 rajveer 3985
            recharge_order.description = "Invalid Device Number"
6092 rajveer 3986
        session.commit()
6048 rajveer 3987
        return False
6031 rajveer 3988
 
6092 rajveer 3989
 
6031 rajveer 3990
def get_user_wallet(userId):
3991
    wallet = UserWallet.get_by(userId = userId)
3992
    if not wallet:
3993
        wallet = UserWallet()
3994
        wallet.amount = 0
3995
        wallet.userId = userId
3996
    return wallet
3997
 
3998
def get_user_wallet_history(userId):
3999
    wallet = get_user_wallet(userId)
4000
    if wallet.id:
4001
        return UserWalletHistory.query.filter_by(wallet = wallet).all()
4002
    else:
4003
        return []
4004
 
6125 rajveer 4005
def get_provider(providerId):
4006
    return ServiceProvider.query.filter_by(id = providerId).one()
4007
 
6048 rajveer 4008
def get_provider_code(providerId):
4009
    return ServiceProvider.query.filter_by(id = providerId).one().code
6031 rajveer 4010
 
6310 anupam.sin 4011
def get_provider_by_code(providerCode):
4012
    return ServiceProvider.query.filter_by(code = providerCode).one()
6049 rajveer 4013
 
6206 rajveer 4014
def get_service_providers(recharge_type, only_active):
4015
    query = ServiceProvider.query.filter_by(type = recharge_type)
4016
    if only_active:
4017
        query = query.filter_by(status = only_active)
4018
    providers = query.all()
6048 rajveer 4019
    serviceProviders = {}
4020
    for provider in providers:
4021
        serviceProviders[provider.id] = provider.name
4022
    return serviceProviders
4023
 
6049 rajveer 4024
def get_service_provider_for_device(rechargeType, deviceNumber):
4025
    if rechargeType == RechargeType.MOBILE:
4026
        serviceType = 'MTP'
4027
    if rechargeType == RechargeType.DTH:
4028
        serviceType = 'RCH'
6048 rajveer 4029
 
6313 anupam.sin 4030
    provider = None
7120 rajveer 4031
    try:
4032
        series = OperatorSeries.get_by(series = int(deviceNumber))
4033
        if series:
7122 rajveer 4034
            providerId = series.operatorId
7120 rajveer 4035
            tc = TelecomCircle.get_by(id = series.circleId)
4036
            operatorCircle = tc.code
6092 rajveer 4037
        else:
7120 rajveer 4038
            l = len(deviceNumber)
4039
            if l < 10:
4040
                deviceNumber = deviceNumber + "0" * (10-l) 
4041
            providerCode, operatorCircle = RechargeService.checkServiceProviderApi(serviceType, deviceNumber)
4042
            if providerCode == 'SNS' or providerCode == '':
4043
                providerId = 0
4044
            else:
4045
                provider = get_provider_by_code(providerCode)
4046
                providerId = provider.id
6049 rajveer 4047
    except:
6092 rajveer 4048
        providerId = -1
6643 rajveer 4049
        operatorCircle = ""
6092 rajveer 4050
 
6289 anupam.sin 4051
    deviceNumberInfo = DeviceNumberInfo()
6336 anupam.sin 4052
    deviceNumberInfo.circleCode = operatorCircle
6289 anupam.sin 4053
    deviceNumberInfo.operatorId = providerId
6313 anupam.sin 4054
    if provider:
4055
        deviceNumberInfo.operatorName = provider.name
6289 anupam.sin 4056
    return deviceNumberInfo
6269 rajveer 4057
 
6591 anupam.sin 4058
def validate_recharge(rechargeType, deviceNumber, userSelectedProviderId, clientAddress):
4059
 
4060
    addressComponents = clientAddress.split('.')
4061
    n = 3
4062
    addressNumber = 0
4063
    for addressComponent in addressComponents :
4064
        addressNumber = addressNumber + (int(addressComponent) * pow(256, n))
4065
        n = n-1
4066
    matchingRow = BlockedIpRange.query.filter(BlockedIpRange.start <= addressNumber).filter(BlockedIpRange.end >= addressNumber).first()
4067
    #if a match is found then check if date has expired.
4068
    if matchingRow :
4069
        #if expiredOn is None that means this range is permanently blocked.
4070
        if matchingRow.expiredOn is None:
4071
            deniedIpAddress = DeniedIpAddress()
4072
            deniedIpAddress.ip = clientAddress
4073
            deniedIpAddress.deniedOn = datetime.datetime.now()
4074
            deniedIpAddress.deviceNumber = deviceNumber
4075
            deniedIpAddress.rechargeType = rechargeType
4076
            session.commit()
4077
            return "Oops! There seems to be a problem. Please try after some time."
4078
        else :
4079
            #if expired is not None and the blockage is still not expired then block the ip.
4080
            if matchingRow.expiredOn > datetime.datetime.now():
4081
                deniedIpAddress = DeniedIpAddress()
4082
                deniedIpAddress.ip = clientAddress
4083
                deniedIpAddress.deniedOn = datetime.datetime.now()
4084
                deniedIpAddress.deviceNumber = deviceNumber
4085
                deniedIpAddress.rechargeType = rechargeType
4086
                session.commit()
4087
                return "Oops! There seems to be a problem. Please try after some time."
4088
 
4089
 
6307 anupam.sin 4090
    deviceNumberInfo = get_service_provider_for_device(rechargeType, deviceNumber)
4091
    if deviceNumberInfo.operatorId == -1:
4092
        return "Oops! There seems to be a problem. Please try after some time."
6336 anupam.sin 4093
    circle = TelecomCircle.query.filter_by(code = deviceNumberInfo.circleCode).first()
6313 anupam.sin 4094
    if circle:
6734 anupam.sin 4095
        serviceAvailability = ServiceAvailability.query.filter_by(circleId = circle.id).filter_by(operatorId = userSelectedProviderId).first()
4096
        if serviceAvailability.permIsServiceAvailable == False or serviceAvailability.tempIsServiceAvailable == False :
4097
 
6313 anupam.sin 4098
            if deviceNumberInfo.operatorName :
6734 anupam.sin 4099
                if serviceAvailability.permIsServiceAvailable == False:
4100
                    return "We currently do not provide service for " + deviceNumberInfo.operatorName + " in " + circle.name + ". We regret the inconvenience."
6314 anupam.sin 4101
                else :
4102
                    return "We are facing technical issues with " + deviceNumberInfo.operatorName + " in " + circle.name + " currently. Please try later." 
6316 anupam.sin 4103
            else :
6734 anupam.sin 4104
                if serviceAvailability.permIsServiceAvailable == False:
4105
                    return "We currently do not provide service for this operator in " + circle.name + ". We regret the inconvenience."
4106
                else:
4107
                    return "We are facing technical issues with this operator in " + circle.name + " currently. Please try later." 
6719 anupam.sin 4108
    totalSuccessfulRechargeAmount = get_previous_transactions(clientAddress)
4109
    if totalSuccessfulRechargeAmount >= 3000 :
4110
        return "You have exceeded your daily recharge limit. Please try after 24 hours."
6269 rajveer 4111
    return "SUCCESS"
6049 rajveer 4112
 
6719 anupam.sin 4113
def get_previous_transactions(clientAddress):
6271 rajveer 4114
    limittime = datetime.datetime.now() - datetime.timedelta(hours=24)
6719 anupam.sin 4115
    totalSuccessfulRechargeAmount = session.query(func.sum(RechargeOrder.totalAmount)).filter(RechargeOrder.status == 5).filter(RechargeOrder.ipAddress == clientAddress).filter(RechargeOrder.creationTimestamp  > limittime).scalar()
4116
    return totalSuccessfulRechargeAmount    
6269 rajveer 4117
 
6031 rajveer 4118
def update_amount_in_wallet(userId, amount, orderId):
4119
    if amount == 0:
4120
        return
4121
    wallet = get_user_wallet(userId)
4122
    wallet.amount = wallet.amount + amount
4123
 
4124
    history = UserWalletHistory()
4125
    history.amount = amount
4126
    history.orderId = orderId
4127
    history.wallet = wallet
4128
    history.timestamp = datetime.datetime.now()
4129
    session.commit()
6056 amit.gupta 4130
 
6094 rajveer 4131
def get_recharge_orders_for_device(deviceNumber):
4132
    orders = MobileRechargeOrder.query.filter_by(mobileNumber = deviceNumber).all()
4133
    if orders is None:
4134
        orders = DTHRechargeOrder.query.filter_by(dthAccountNumber = deviceNumber).all()
4135
    return orders
4136
 
6154 rajveer 4137
def get_recharge_orders_for_status(status):
4138
    if status == -1:
6161 rajveer 4139
        orders = RechargeOrder.query.order_by(desc(RechargeOrder.id)).all()
6154 rajveer 4140
    else:
6161 rajveer 4141
        orders = RechargeOrder.query.order_by(desc(RechargeOrder.id)).filter_by(status = status).all()
6154 rajveer 4142
    return orders
4143
 
6188 rajveer 4144
def get_recharge_statistics():
4145
    rs = RechargeStatistics()
4146
    statusCounts = {}
4147
    operatorCounts = {}
4148
    currentOrders = {}
4149
    amounts = {}
4150
 
4151
    sorders = session.query(RechargeOrder.status, func.count(RechargeOrder.status)).group_by(RechargeOrder.status).all()
4152
    for sorder in sorders:
6190 rajveer 4153
        statusCounts[sorder[0]] = sorder[1]
6188 rajveer 4154
 
4155
    oorders = session.query(MobileRechargeOrder.mobileOperatorId, func.count(MobileRechargeOrder.mobileOperatorId)).group_by(MobileRechargeOrder.mobileOperatorId).all()
4156
    for oorder in oorders:
6190 rajveer 4157
        operatorCounts[oorder[0]] = oorder[1]
6188 rajveer 4158
 
4159
    oorders = session.query(DTHRechargeOrder.dthOperatorId, func.count(DTHRechargeOrder.dthOperatorId)).group_by(DTHRechargeOrder.dthOperatorId).all()
4160
    for oorder in oorders:
6190 rajveer 4161
        operatorCounts[oorder[0]] = oorder[1]
6188 rajveer 4162
 
6219 rajveer 4163
    forders = RechargeOrder.query.order_by(desc(RechargeOrder.id)).filter_by(status = RechargeOrderStatus.RECHARGE_FAILED).limit(20).all()
6188 rajveer 4164
    currentOrders[RechargeOrderStatus._VALUES_TO_NAMES.get(RechargeOrderStatus.RECHARGE_FAILED)] = [order.to_thrift_object() for order in forders]
4165
    sorders = RechargeOrder.query.order_by(desc(RechargeOrder.id)).filter_by(status = RechargeOrderStatus.RECHARGE_SUCCESSFUL).limit(20).all()
6197 rajveer 4166
    currentOrders[RechargeOrderStatus._VALUES_TO_NAMES.get(RechargeOrderStatus.RECHARGE_SUCCESSFUL)] = [order.to_thrift_object() for order in sorders]
6216 rajveer 4167
    porders = RechargeOrder.query.order_by(desc(RechargeOrder.id)).filter_by(status = RechargeOrderStatus.PAYMENT_SUCCESSFUL).limit(20).all()
4168
    currentOrders[RechargeOrderStatus._VALUES_TO_NAMES.get(RechargeOrderStatus.PAYMENT_SUCCESSFUL)] = [order.to_thrift_object() for order in porders]
6238 rajveer 4169
    rorders = RechargeOrder.query.order_by(desc(RechargeOrder.id)).filter_by(status = RechargeOrderStatus.RECHARGE_FAILED_REFUNDED).limit(20).all()
4170
    currentOrders[RechargeOrderStatus._VALUES_TO_NAMES.get(RechargeOrderStatus.RECHARGE_FAILED_REFUNDED)] = [order.to_thrift_object() for order in rorders]
6188 rajveer 4171
 
6190 rajveer 4172
    twa = session.query(func.sum(UserWallet.amount)).one()
4173
    tra = session.query(func.sum(RechargeOrder.totalAmount)).filter(RechargeOrder.status == RechargeOrderStatus.RECHARGE_SUCCESSFUL).one()
4174
    gwa = session.query(func.sum(UserWalletHistory.amount)).filter(UserWalletHistory.orderId > 100000).one()
6278 rajveer 4175
    #tpa = session.query(func.sum(UserWalletHistory.amount)).filter(UserWalletHistory.orderId < 100000).one()
6482 rajveer 4176
    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()
4177
    tda = session.query(func.sum(RechargeOrder.couponAmount)).filter(RechargeOrder.status == RechargeOrderStatus.RECHARGE_SUCCESSFUL).one()
4178
 
6346 rajveer 4179
    balance = RechargeService.getBalance()
6305 rajveer 4180
    amounts['(a) Total Payment Amount'] = tpa[0]
4181
    amounts['(b) Gift Wallet Amount'] = gwa[0]
4182
    amounts['(c) Total Wallet Amount'] = twa[0]
4183
    amounts['(d) Total Recharge Amount'] = tra[0]
4184
    amounts['(e) Account Balance'] = balance
6482 rajveer 4185
    amounts['(f) Discount Balance'] = tda[0]
6278 rajveer 4186
    #amounts['Total Payment Amount'] = tra[0] + twa[0] - gwa[0]
6524 rajveer 4187
    amounts['Saholic Mismatch = (a+b+f-c-d)'] = tpa[0] + gwa[0] + tda[0] - tra[0] - (twa[0] + 63774)
4188
    amounts['SpiceDeck Mismatch = (d-e)'] = tra[0] + balance - 750000 
6278 rajveer 4189
 
6337 rajveer 4190
    '''
6318 rajveer 4191
    if amounts['SpiceDeck Mismatch = (d-e)'] != -739:
4192
        mail(mail_user, mail_password, ['rajneesh.arora@shop2020.in', 'rajveer.singh@shop2020.in', 'anupam.singh@shop2020.in'], "SpiceDeck Account mismatch of amount " + str(amounts['SpiceDeck Mismatch = (d-e)']), "", [], [], [])
4193
    if amounts['Saholic Mismatch = (a+b-c-d)'] != -1919:
4194
        mail(mail_user, mail_password, ['rajneesh.arora@shop2020.in', 'rajveer.singh@shop2020.in', 'anupam.singh@shop2020.in'], "Saholic Recharge Account mismatch of amount " + str(amounts['Saholic Mismatch = (a+b-c-d)']), "", [], [], [])
6337 rajveer 4195
    '''
6318 rajveer 4196
 
6188 rajveer 4197
    rs.statusCounts = statusCounts
4198
    rs.operatorCounts = operatorCounts    
4199
    rs.currentOrders = currentOrders
4200
    rs.amounts = amounts
4201
 
4202
    return rs
4203
 
4204
 
6159 rajveer 4205
def get_plans_for_operator(operator_id):
4206
    return RechargePlan.query.filter_by(operatorId = operator_id).all()
4207
 
6056 amit.gupta 4208
def get_recharge_orders_for_transaction(txId):
4209
    return RechargeOrder.query.filter_by(transaction_id = txId).first()
6102 rajveer 4210
 
6285 rajveer 4211
def enqueue_recharge_info_email(recharge_order, gvs={}):
6102 rajveer 4212
    status = ""
4213
    message = ""
4214
    html_header = """
4215
 
4216
    <html>
4217
    <body>
4218
    <div>
4219
        <p>
4220
            Hello $email,<br /><br />
6127 rajveer 4221
            Thanks for placing recharge order with us. Following are the details of your recharge order:
6102 rajveer 4222
        </p>
4223
        <div>
6136 rajveer 4224
            Order Id : $order_id <br/>
4225
            Order Date : $order_date <br/>
4226
            Order Amount : Rs. $order_amount <br/>
4227
            Order Status : $order_status <br/>
4228
            Device Number : $device_number <br/>
4229
            Service Provider : $service_provider <br/>
6102 rajveer 4230
        </div>
6348 rajveer 4231
    <br />
6102 rajveer 4232
    """
6288 rajveer 4233
 
4234
    FailureReasonMap = {}
4235
    FailureReasonMap["Invalid Amount"] = "the amount you tried seems to be invalid. Please try another amount."
4236
    FailureReasonMap["Customer Exceeded Daily Limit"] = "you have exceeded daily recharge limit for this number. Please try after 12 hours."
6399 rajveer 4237
    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."
6288 rajveer 4238
 
4239
    failureReason = FailureReasonMap.get(recharge_order.description)
4240
    if failureReason is None:
4241
        failureReason = "of network failure."
6102 rajveer 4242
    if recharge_order.status == RechargeOrderStatus.RECHARGE_SUCCESSFUL:
4243
        status = "Recharge Successful"
4244
        message = ""
6444 rajveer 4245
        if recharge_order.couponAmount > 0:
4246
            message = message + "<b>You have used coupon " + recharge_order.couponCode + " and got discount of Rs. " + str(recharge_order.couponAmount) + ".</b>" 
4247
 
6102 rajveer 4248
    elif recharge_order.status == RechargeOrderStatus.RECHARGE_FAILED:
4249
        status = "Recharge Failed"
6127 rajveer 4250
        message = """
6288 rajveer 4251
                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>
6127 rajveer 4252
                """
6206 rajveer 4253
    elif recharge_order.status == RechargeOrderStatus.PAYMENT_SUCCESSFUL:
6102 rajveer 4254
        status = "Recharge Under Process"
6127 rajveer 4255
        message = """
6288 rajveer 4256
                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>
6127 rajveer 4257
                """
6279 rajveer 4258
    elif recharge_order.status == RechargeOrderStatus.RECHARGE_FAILED_REFUNDED:
4259
        status = "Recharge Failed, Amount Refunded"
4260
        message = """
4261
                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>
4262
                """
6285 rajveer 4263
    if len(gvs) > 0:
6340 rajveer 4264
        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>'
6330 rajveer 4265
        message = message + " <br />  <b>Voucher Code &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Amount</b>"
6285 rajveer 4266
        for gv in gvs.keys():
4267
            gvAmount = gvs.get(gv)
6330 rajveer 4268
            message = message + " <br />  <b>" + gv + "&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Rs. "  + str(gvAmount) + "</b>"
6285 rajveer 4269
 
6114 rajveer 4270
    message = message  + '<br />  In case of any problem, please  <a href="$source_url/contact-us">contact us</a>'
6102 rajveer 4271
 
6136 rajveer 4272
    html_header = html_header + message
6102 rajveer 4273
    html_footer = """
4274
    <p>
4275
        Best Wishes,<br />
4276
        $source_name Team
4277
    </p>
4278
    </div>
4279
    </body>
4280
    </html>
4281
    """
4282
 
6125 rajveer 4283
    if isinstance(recharge_order, MobileRechargeOrder):
4284
        deviceNumber = recharge_order.mobileNumber
4285
        providerName = get_provider(recharge_order.mobileOperatorId).name
4286
    if isinstance(recharge_order, DTHRechargeOrder):
4287
        deviceNumber = recharge_order.dthAccountNumber
4288
        providerName = get_provider(recharge_order.dthOperatorId).name
4289
 
6127 rajveer 4290
    display_order_id = recharge_order.idPrefix + str(recharge_order.id)
6102 rajveer 4291
    email = recharge_order.userEmailId
4292
    dt = datetime.datetime.strptime(str(recharge_order.creationTimestamp), "%Y-%m-%d %H:%M:%S")
4293
    formated_order_date = dt.strftime("%A, %d. %B %Y %I:%M%p")
4294
 
6288 rajveer 4295
    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))
6102 rajveer 4296
    email_footer = Template(html_footer).substitute(dict(source_url = source_url, source_name = source_name))
4297
 
4298
    try:
4299
        helper_client = HelperClient().get_client()
6906 rajveer 4300
        helper_client.saveUserEmailForSending([email], "", source_name + " - Recharge Order Details", email_header + email_footer, str(recharge_order.id), "RechargeInfo", [], [])
6102 rajveer 4301
        return True
4302
    except Exception as e:
4303
        print e
4304
        return False
4305
 
6307 anupam.sin 4306
def get_recharge_denominations(operator_id, circleCode, denomination_type):
4307
    circle_id = TelecomCircle.query.filter_by(code = circleCode).first().id
6289 anupam.sin 4308
    return RechargeDenomination.query.filter_by(operatorId = operator_id).filter_by(circleId = circle_id).filter_by(denominationType = denomination_type).all()
6371 rajveer 4309
 
4310
def update_availability_status(operatorId, circleId, isAvailable):
4311
    serviceAvailability = ServiceAvailability.query.filter_by(circleId = circleId).filter_by(operatorId = operatorId).first()
6734 anupam.sin 4312
    serviceAvailability.tempIsServiceAvailable = isAvailable
6371 rajveer 4313
    session.commit()
4314
 
6389 rajveer 4315
def get_misc_charges(transactionId):
4316
    retCharges = {}
4317
    miscCharges = MiscCharges.get_by(transaction_id = transactionId)
4318
    if miscCharges:
6426 rajveer 4319
        retCharges[1] = miscCharges.chargeAmount 
6389 rajveer 4320
    return retCharges
6396 amit.gupta 4321
 
4322
def get_available_emi_schemes():
4323
    t_emi_schemes = []
4324
    emi_schemes = EmiScheme.query.all()
4325
    if emi_schemes:
4326
        t_emi_schemes = [to_t_emi_scheme(emi_scheme) for emi_scheme in emi_schemes]
4327
    return t_emi_schemes
6389 rajveer 4328
 
6507 anupam.sin 4329
def refund_recharge_order(rechargeOrderId):
4330
    try :
4331
        rechargeOrder = RechargeOrder.query.filter_by(id = rechargeOrderId).first()
4332
        wallet = UserWallet.query.filter_by(userId = rechargeOrder.userId).first()
4333
    except:
4334
        return False
4335
 
4336
    paidAmount = rechargeOrder.totalAmount - rechargeOrder.walletAmount - rechargeOrder.couponAmount
4337
    amountToRefund = 0
4338
    status = None
4339
    if (paidAmount <= wallet.amount) :
4340
        amountToRefund = paidAmount
4341
        status = RechargeOrderStatus.REFUNDED
4342
    else :
4343
        amountToRefund = wallet.amount
4344
        status = RechargeOrderStatus.PARTIALLY_REFUNDED
4345
 
4346
    update_amount_in_wallet(rechargeOrder.userId, -amountToRefund, rechargeOrderId)
4347
 
4348
    try:    
4349
        pc = PaymentClient().get_client()
4350
        if pc.refundPayment(rechargeOrder.transaction_id, amountToRefund, True) :
4351
            rechargeOrder.status = status
6515 anupam.sin 4352
            rechargeOrder.refundTimestamp = datetime.datetime.now()
6507 anupam.sin 4353
            session.commit()
4354
            return True
4355
        else :
4356
            update_amount_in_wallet(rechargeOrder.userId, amountToRefund, rechargeOrderId)
4357
 
4358
    except:
4359
        update_amount_in_wallet(rechargeOrder.userId, amountToRefund, rechargeOrderId)
4360
 
4361
    return False 
4362
 
6821 amar.kumar 4363
def get_physical_orders(from_date, to_date):
4364
    query = Order.query.filter(Order.created_timestamp >from_date).filter(Order.created_timestamp < to_date).filter(Order.status>=2)
4365
    return query.all()
4366
 
6507 anupam.sin 4367
 
766 rajveer 4368
def close_session():
4369
    if session.is_active:
4370
        print "session is active. closing it."
2783 chandransh 4371
        session.close()
3376 rajveer 4372
 
4373
def is_alive():
4374
    try:
4375
        session.query(Transaction.id).limit(1).one()
4376
        return True
4377
    except:
6000 mandeep.dh 4378
        return False
4379
 
6906 rajveer 4380
def get_document(docType, docSource):
4381
    document = DocumentStore.get_by(docType = docType, docSource = docSource)
4382
    if document:
4383
        return document.document
4384
    else:
7040 amar.kumar 4385
        return bin(0)
6906 rajveer 4386
 
7075 rajveer 4387
def retrieve_invoice(orderId, userId):
4388
    order = get_order(orderId)
4389
    if order.customer_id != userId:
4390
        return bin(0)
6988 rajveer 4391
    strOrderId = '0'*(10-len(str(orderId)))+str(orderId)
7072 rajveer 4392
    filename = "/SaholicInvoices/" + strOrderId[0:2] + "/" + strOrderId[2:4] + "/" + strOrderId[4:6] + "/" + str(orderId) + ".pdf"  
6988 rajveer 4393
    file = open(filename, "rb")
4394
    pdfFile = file.read()
4395
    return pdfFile
4396
 
6906 rajveer 4397
def myFirstPage(canvas, doc):
4398
    canvas.saveState()
6916 anupam.sin 4399
    canvas.setTitle("Theft-Insurance-Policy")
6906 rajveer 4400
    canvas.restoreState()
4401
 
4402
 
4403
def __generate_policy_doc(order, filename):
6903 anupam.sin 4404
    PAGE_HEIGHT=defaultPageSize[1]; PAGE_WIDTH=defaultPageSize[0]
4405
    styles = getSampleStyleSheet()
4406
    styles.add(ParagraphStyle(name='left', leftIndent=12,fontSize=11), alias='li')
4407
    styles.add(ParagraphStyle(name='bullet', bulletIndent=24, leftIndent=24), alias='bull')
6916 anupam.sin 4408
    styles.add(ParagraphStyle(name='insurerName', alignment=TA_CENTER, fontName="Times-Bold", fontSize=16), alias='iN')
4409
    styles.add(ParagraphStyle(name='insurerAdd', alignment=TA_CENTER, fontName="Helvetica",leading=15, fontSize=12), alias='iA')
4410
    styles.add(ParagraphStyle(name='subHeading', alignment=TA_CENTER, fontName="Helvetica", fontSize=13), alias='sH')
6903 anupam.sin 4411
 
6914 rajveer 4412
    invoiceNumber = str(order.invoice_number)
6906 rajveer 4413
    billing_timestamp = str(order.billing_timestamp.date()) 
6903 anupam.sin 4414
 
6906 rajveer 4415
    doc = SimpleDocTemplate(filename)
6916 anupam.sin 4416
    Story = [Spacer(0, 0)]
6903 anupam.sin 4417
    style = styles["Normal"]
6916 anupam.sin 4418
 
4419
 
4420
    file_name = os.path.dirname(os.path.realpath(__file__)) + '/../resources/nia-logo.jpg'
4421
    image = Image(file_name, width=100, height=100)
4422
    Story.append(image)
4423
    Story.append(Spacer(1,0.2*inch))
4424
 
4425
    text = ("""<u>The New India Assurance Company Limited</u>""") 
4426
    p = Paragraph(text, styles['insurerName'])
4427
    Story.append(p)
4428
    Story.append(Spacer(1,0.2*inch))
4429
 
4430
    text = ("""DO-IX, 35/1, Fortune Park, 1st Floor, Park Road, Tasker Town, Shivajinagar, Bangalore  560051""") 
4431
    p = Paragraph(text, styles['insurerAdd'])
4432
    Story.append(p)
4433
    Story.append(Spacer(1,0.3*inch))
4434
 
4435
    text = ("""MOBILE HAND SET INSURANCE – THEFT & BURGLARY RISKS ONLY""")
4436
    p = Paragraph(text, styles['subHeading'])
4437
    Story.append(p)
4438
    Story.append(Spacer(1,1*inch))
4439
 
6903 anupam.sin 4440
    text = ("""<u><b>Subject Matter Of Insurance</b></u> : <i>New Mobile Handsets</i> alone and <i>Tablets with 'Voice Calls'</i> only. 
4441
    Sold 'online' by <b>Spice Online Retail Private Limited, New Delhi</b>, to its customers.""") 
4442
    p = Paragraph(text, style)
4443
    Story.append(p)
4444
    Story.append(Spacer(1,0.2*inch))
4445
    text = ("""Insurer will indemnify the Insured in the event of Theft/Burglary of <i>Mobile Handsets</i> 
6914 rajveer 4446
    alone and <i>Tablets with 'Voice Calls'</i> only sold as per Invoice No. %s
6903 anupam.sin 4447
    dated %s and insured with THE NEW INDIA ASSURANCE COMPANY LIMITED, BANGALORE, as per Policy No. 671700/46/12/2400000008,  
4448
    for a period of 12 months from the date and time of delivery of Mobile Handset to the customer.""" % (invoiceNumber, billing_timestamp)) 
4449
    p = Paragraph(text, style)
4450
    Story.append(p)
4451
    Story.append(Spacer(1,0.2*inch))
4452
    text = ("""<b>WARRANTY</b> -  Warranted that the Mobile Handset sold during the Policy Period of 25/02/2013 to 24/02/2014
4453
             are only covered irrespective of date of delivery to the customer""")
4454
    p = Paragraph(text, style)
4455
    Story.append(p)
4456
    Story.append(Spacer(1,0.2*inch))
6915 anupam.sin 4457
    text = ("<b>INSURER</b> -The New India Assurance company limited.")
6903 anupam.sin 4458
    p = Paragraph(text, style)
4459
    Story.append(p)
4460
    Story.append(Spacer(1,0.2*inch))
4461
    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.") 
4462
    p = Paragraph(text, style)
4463
    Story.append(p)
4464
    Story.append(Spacer(1,0.2*inch))
4465
    text = ("<b>GEOGRAPHICAL LIMIT</b> – World-wide") 
4466
    p = Paragraph(text, style)
4467
    Story.append(p)
4468
    Story.append(Spacer(1,0.2*inch))
4469
    text = ("<b>RISK COVERAGE</b> – Theft and/or burglary only") 
4470
    p = Paragraph(text, style)
4471
    Story.append(p)
6916 anupam.sin 4472
    Story.append(Spacer(1,0.4*inch))
6915 anupam.sin 4473
    text = ("Terms and Conditions of Insurance:") 
4474
    p = Paragraph(text, styles["h2"])
4475
    Story.append(p)
4476
    Story.append(Spacer(1,0.1*inch))
4477
    text = ("""Insurance Premium paid will not be refunded.""")
4478
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4479
    Story.append(p)
4480
    Story.append(Spacer(1,0.1*inch))
6921 anupam.sin 4481
    text = ("""Claims will be settled by UIB on behalf of The New India Assurance Co. Ltd.<br></br>
4482
            Saholic.com will not be responsible for claim approval and disbursement.""")
4483
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4484
    Story.append(p)
4485
    Story.append(Spacer(1,0.1*inch))
6915 anupam.sin 4486
    text = ("""Insurance will be invalidated for returned products.""")
4487
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4488
    Story.append(p)
6921 anupam.sin 4489
    Story.append(Spacer(1,0.3*inch))
6903 anupam.sin 4490
    text = ("Exclusions:") 
4491
    p = Paragraph(text, styles["h2"])
4492
    Story.append(p)
4493
    Story.append(Spacer(1,0.1*inch))
4494
    text = ("Insurer is not liable") 
4495
    p = Paragraph(text, styles["left"])
4496
    Story.append(p)
4497
    Story.append(Spacer(1,0.1*inch))
4498
    text = ("If the handset is not connected to Mobile Service Provider Network")
4499
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4500
    Story.append(p)
4501
    Story.append(Spacer(1,0.1*inch))
4502
    text = ("Caused by incorrect storage, poor care and maintenance, careless use, negligence.")
4503
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4504
    Story.append(p)
4505
    Story.append(Spacer(1,0.1*inch))
4506
    text = ("Due to mysterious disappearance, forgotten or misplaced or Lost or if handset is left unattended at any point of time.")
4507
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4508
    Story.append(p)
4509
    Story.append(Spacer(1,0.1*inch))
4510
    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.")
4511
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4512
    Story.append(p)
4513
    Story.append(Spacer(1,0.1*inch))
4514
    text = ("Caused whilst engaging in criminal acts.")
4515
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4516
    Story.append(p)
4517
    Story.append(Spacer(1,0.1*inch))
4518
    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.")
4519
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4520
    Story.append(p)
4521
    Story.append(Spacer(1,0.1*inch))
4522
    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.")
4523
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4524
    Story.append(p)
4525
    Story.append(Spacer(1,0.1*inch))
4526
    text = ("Loss of mobile handset due to theft from the building unless there is visible forcible entry/exit into/from the building.")
4527
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4528
    Story.append(p)
4529
    Story.append(Spacer(1,0.1*inch))
4530
    text = ("If the documents are found to be tampered; non-disclosure of material fact, fraud/misrepresentation.")
4531
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4532
    Story.append(p)
4533
    Story.append(Spacer(1,0.1*inch))
4534
    text = ("The policy is not transferable.")
4535
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4536
    Story.append(p)
4537
    Story.append(Spacer(1,0.2*inch))
4538
 
4539
    text = ("Claim Procedure:") 
4540
    p = Paragraph(text, styles["h2"])
4541
    Story.append(p)
4542
    Story.append(Spacer(1,0.1*inch))
4543
    text = ("""For Theft or Burglary of the handset immediate intimation to be given
4544
     to the police within 48 hours of occurrence of incident and proper documents to be obtained 
4545
     and inform the service provider within 48 hours about theft of handset in order to block the SIM services.""")
4546
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4547
    Story.append(p)
4548
    Story.append(Spacer(1,0.1*inch))
4549
    text = ("""To intimate Insurance Company about the loss of Mobile Handset within 48 hours 
6915 anupam.sin 4550
     through Call Centre No.022-49107910 OR through e-mail <u>saholic.claims@universalinsurance.co.in</u> OR through 
6903 anupam.sin 4551
     written communication to <i>Universal Insurance brokers (UIB) No.304, Commerce House, 9/1,Cunningham Road, Bangalore – 560052</i>.""")
4552
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4553
    Story.append(p)
4554
    Story.append(Spacer(1,0.1*inch))
6915 anupam.sin 4555
    text = ("""Claim documents can be downloaded through UIB Website <u>http://www.universalinsurance.co.in/mobileinsurance/claiminfo.html</u>
4556
    <br></br>To know or track your claim please contact Call Centre No. 022-49107910 of Universal Insurance brokers (UIB). """)
6903 anupam.sin 4557
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4558
    Story.append(p)
4559
    Story.append(Spacer(1,0.1*inch))
4560
    text = ("""All the completed claim documents to reach ‘Universal Insurance Brokers (UIB)’ office 
4561
    at <i>No.304, Commerce House, 9/1, Cunningham Road, Bangalore – 560052</i> <b>within 21 days</b>.""")
4562
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4563
    Story.append(p)
4564
    Story.append(Spacer(1,0.2*inch))
4565
 
4566
 
4567
    text = ("Excess(Minimum Deduction):") 
4568
    p = Paragraph(text, styles["h2"])
4569
    Story.append(p)
4570
    Story.append(Spacer(1,0.1*inch))
4571
    text = ("""The excess will be 5% of the value of each claim subject to a minimum of Rs.500/-""")
4572
    p = Paragraph(text, styles["left"])
4573
    Story.append(p)
4574
    Story.append(Spacer(1,0.2*inch))
4575
 
4576
    text = ("Depreciation:") 
4577
    p = Paragraph(text, styles["h2"])
4578
    Story.append(p)
4579
    Story.append(Spacer(1,0.1*inch))
4580
 
4581
    text = ("For 0 – 60 days, 15%")
4582
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4583
    Story.append(p)
4584
    Story.append(Spacer(1,0.1*inch))
4585
 
4586
    text = ("61-150 days, 30%")
4587
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4588
    Story.append(p)
4589
    Story.append(Spacer(1,0.1*inch))
4590
 
4591
    text = ("151 – 365 days, 45%")
4592
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4593
    Story.append(p)
4594
    Story.append(Spacer(1,0.4*inch))
4595
 
4596
    text = ("<i>Insurance is a subject matter of solicitation.</i>")
4597
    p = Paragraph(text, style)
4598
    Story.append(p)
4599
    Story.append(Spacer(1,0.2*inch))
4600
 
6906 rajveer 4601
    doc.build(Story, onFirstPage=myFirstPage)
6980 anupam.sin 4602
 
4603
def drawLine(Story, style):
4604
    Story.append(Paragraph('-'*40, style))
6915 anupam.sin 4605
 
6980 anupam.sin 4606
def generateHotSpotInvoice():
4607
 
4608
    ##########TO BE PASSED TO THIS METHOD####################################
4609
    #########################################################################
4610
    filename = "/home/anupam/test.pdf"                             ##########
4611
    itemCode = "SPICEMI450WHT"                                     ##########
4612
    lotNumber = "12345678901234"                                   ##########
4613
    itemName = "Spice Stellar Craze Mi-450 White"                  ##########
4614
    qty = 1                                                        ##########
4615
    unitPrice = 3099.50                                            ##########
4616
    vat = 310.23                                                   ##########
4617
    billingTime = datetime.datetime.now()                          ##########
4618
    invNum = "885182994"                                           ##########
4619
    counter = 1                                                    ##########
4620
    ourInvoiceNum = "209809"                                       ##########
4621
    customerId = "12345678909"                                     ##########
4622
    customerName = "ANUPAM PRATAP SINGH"                           ##########
4623
    telNum = ""                                                    ##########
4624
    #########################################################################
4625
 
4626
    PAGE_HEIGHT=defaultPageSize[1];
4627
    styles = getSampleStyleSheet()
4628
    styles.add(ParagraphStyle(name='prologue', alignment=TA_CENTER, fontName="Courier", rightIndent = 5, fontSize=10), alias='sH')
4629
    styles.add(ParagraphStyle(name='text', alignment=TA_JUSTIFY, fontName="Courier", fontSize=10), alias='text')
4630
    styles.add(ParagraphStyle(name='line', alignment=TA_CENTER, fontName="Courier", fontSize=10), alias='line')
4631
    styles.add(ParagraphStyle(name='epilogue', alignment=TA_CENTER, fontName="Courier", leftIndent = 30, rightIndent=36, fontSize=10), alias='ep')
4632
 
4633
    Story = []
4634
    prologueStyle = styles["prologue"]
4635
    lineStyle = styles["line"]
4636
    textStyle = styles["text"]
4637
    epilogueStyle = styles["epilogue"]
4638
 
4639
    doc = BaseDocTemplate(filename,showBoundary=0)
4640
 
4641
    #Two Columns
4642
    frame1 = Frame(58, doc.bottomMargin, doc.width/2 + 25, doc.height + 7, id='col1')
4643
 
4644
 
4645
 
4646
    Story.append(Paragraph("""Spice Retail Limited<br></br>
4647
        C/O,PIBCO LIMITED,Basement,Punjsons<br></br>
4648
        2,Kalkaji Industrial Area,New Delhi<br></br>
4649
          .<br></br>
4650
        TIN NO. 07430284979<br></br>
4651
        Service Tax No:AAACM0294PST001<br></br>
4652
        D U P L I C A T E<br></br>
4653
        I N V O I C E<br></br>""", prologueStyle))
4654
    drawLine(Story, lineStyle)
4655
 
4656
    Story.append(Paragraph('{0:7s}{1:>11s}{2:  %d/%m/%Y  %H:%M:%S}'.format("INV NO:", invNum, billingTime).replace(" ", "&nbsp;"), textStyle))
4657
    Story.append(Paragraph("{0:8s}{1:>5d}{2:>11s}{3:>11s}".format('COUNTER:', counter, "CASHIER:", "SUPERADMIN").replace(" ", "&nbsp;"), textStyle))
4658
    Story.append(Paragraph("MN INV NO&amp;DT: {0:<13s}{1:%d/%m/%Y}   ".format(ourInvoiceNum, billingTime).replace(" ", "&nbsp;"), textStyle))
4659
    drawLine(Story, lineStyle)
4660
 
4661
    Story.append(Paragraph("{0:<13s}{1:<27s}".format("CUSTOMER ID:", customerId).replace(" ", "&nbsp;"), textStyle))
4662
    Story.append(Paragraph("{0:<6s}{1:<34s}".format("NAME:", customerName + " " + ourInvoiceNum).replace(" ", "&nbsp;"), textStyle))
4663
    Story.append(Paragraph("{0:<9s}{1:<31s}".format("TEL NO.:", telNum).replace(" ", "&nbsp;"), textStyle))
4664
    drawLine(Story, lineStyle)
4665
 
4666
    Story.append(Paragraph("ITEM" + "&nbsp;"*12 + "LOT NUMBER<br></br>" + \
4667
                            "&nbsp;ITEM NAME<br></br>" + \
4668
                            "&nbsp;"*5 + "QTY" + "&nbsp;"*21 + "AMOUNT(INR)", textStyle))
4669
    drawLine(Story, lineStyle)
4670
 
4671
    Story.append(Paragraph(('{0:<16s}{1:24s}').format(itemCode, lotNumber).replace(' ', '&nbsp;'),textStyle))
4672
    Story.append(Paragraph((' {0:<39s}').format(itemName).replace(' ', '&nbsp;'),textStyle))
4673
    Story.append(Paragraph(('{0:<3d}{1:>10s}{2:13.2f}{3:14.2f}').format(qty, 'PCS', unitPrice, qty*unitPrice).replace(' ', '&nbsp;'),textStyle))
4674
    Story.append(Paragraph(('{0:<3s}{1:37.2f}').format("VAT", vat).replace(' ', '&nbsp;'),textStyle))
4675
    Story.append(Paragraph(('{0:<10s}{1:30.2f}').format("ITEM TOTAL", vat + unitPrice*qty).replace(' ', '&nbsp;'),textStyle))
4676
 
4677
    drawLine(Story, lineStyle)
4678
    Story.append(Paragraph(('{0:13s}{1:>12s}{2:15.2f}').format("GROSS TOTAL:","INR", vat + unitPrice*qty).replace(' ', '&nbsp;'),textStyle))
4679
    drawLine(Story, lineStyle)
4680
 
4681
    Story.append(Paragraph(('{0:13s}{1:>12s}{2:15.2f}').format("NET TOTAL:","INR", vat + unitPrice*qty).replace(' ', '&nbsp;'),textStyle))
4682
    Story.append(Paragraph(('{0:13s}{1:>12s}{2:15.2f}').format("NET VAT:","INR", vat).replace(' ', '&nbsp;'),textStyle))
4683
    drawLine(Story, lineStyle)
4684
 
4685
    Story.append(Paragraph(('{0:13s}{1:>12s}{2:15.2f}').format("SPICE ONLINE:","INR", vat + unitPrice*qty).replace(' ', '&nbsp;'),textStyle))
4686
    drawLine(Story, lineStyle)
4687
 
4688
    Story.append(Paragraph(('{0:16s}{1:>4d}').format("NUMBER OF ITEMS:",qty,).replace(' ', '&nbsp;'),textStyle))
4689
    Story.append(Paragraph(('{0:16s}{1:>9.6f}').format("TOTAL ITEMS    :",qty,).replace(' ', '&nbsp;'),textStyle))
4690
 
4691
    Story.append(Paragraph("Goods once Sold Will not be taken back.<br></br>All Disputes subject to Delhi Jurisdiction",epilogueStyle))
4692
 
4693
 
4694
    doc.addPageTemplates([PageTemplate(id='TwoCol',frames=[frame1]), ])
4695
 
4696
    #start the construction of the pdf
4697
    doc.build(Story)
4698
 
6985 anupam.sin 4699
def change_shipping_address(orderId, line1, line2, city, state, pin):
4700
    order = Order.get_by(id = orderId)
4701
    if order:
4702
        order.customer_address1 = line1
4703
        order.customer_address2 = line2
4704
        order.customer_city = city
4705
        order.customer_state = state
7364 manish.sha 4706
 
4707
        # Start:- Added/Modified by Manish Sharma on 13 May 2013 for Change Shipping Address functionality
4708
        if order.customer_pincode != pin :
4709
            type = DeliveryType.PREPAID
4710
            if order.cod:
4711
                type = DeliveryType.COD
4712
            logistics_client = LogisticsClient().get_client()
4713
            logistics_info = logistics_client.getLogisticsEstimation(order.lineitems[0].item_id, pin, type)
4714
 
4715
            # Check for new estimate. Raise exception if new address is not serviceable
4716
            if logistics_info.deliveryTime == -1:
4717
                raise TransactionServiceException(1, 'Location not serviceable')
4718
 
4719
            # COD services are not available everywhere
4720
            if order.cod:
4721
                if not logistics_info.codAllowed:
4722
                    raise TransactionServiceException(2, 'COD service not available')
4723
 
4724
            logistics_info_new = logistics_client.getLogisticsInfo(pin, order.lineitems[0].item_id, type, PickUpType.COURIER)
4725
            order.tracking_id = logistics_info_new.airway_billno
4726
            order.airwaybill_no = logistics_info_new.airway_billno
4727
            order.logistics_provider_id = logistics_info_new.providerId
4728
            current_time = datetime.datetime.now()
4729
 
4730
            logistics_info.deliveryTime = adjust_delivery_time(current_time, logistics_info.deliveryTime)
4731
            logistics_info.shippingTime = adjust_delivery_time(current_time, logistics_info.shippingTime)
4732
            logistics_info.deliveryDelay = adjust_delivery_time(current_time, (logistics_info.shippingTime+logistics_info.deliveryDelay))
4733
            new_expected_shipping_time_cod = (current_time + datetime.timedelta(days=logistics_info.shippingTime)).replace(hour=COD_SHIPPING_CUTOFF_TIME, minute=0, second=0)
4734
            new_expected_shipping_time_prepaid = (current_time + datetime.timedelta(days=logistics_info.shippingTime)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
4735
 
4736
            if order.cod:
4737
                if order.expected_shipping_time.date() == new_expected_shipping_time_cod.date() :
4738
                    if order.otg :
4739
                        order.otg = logistics_info.otgAvailable 
4740
                else:
4741
                    if order.otg:
4742
                        order.otg = False
4743
                order.expected_shipping_time = new_expected_shipping_time_cod
4744
                order.expected_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryTime)).replace(hour=COD_SHIPPING_CUTOFF_TIME, minute=0, second=0)
4745
                order.courier_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryDelay)).replace(hour=COD_SHIPPING_CUTOFF_TIME, minute=0, second=0)
4746
            else:
4747
                if order.expected_shipping_time.date() == new_expected_shipping_time_prepaid.date() :
4748
                    if order.otg :
4749
                        order.otg = logistics_info.otgAvailable 
4750
                else:
4751
                    if order.otg:
4752
                        order.otg = False
4753
                order.expected_shipping_time = new_expected_shipping_time_prepaid
4754
                order.expected_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryTime)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
4755
                order.courier_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryDelay)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
4756
 
4757
        order.customer_pincode = pin
4758
        # End:- Added/Modified by Manish Sharma on 13 May 2013 for Change Shipping Address functionality
6985 anupam.sin 4759
        session.commit()
4760
        return True
4761
    return False
4762
 
7084 rajveer 4763
def get_recharge_transactions(storeId):
4764
    query = RechargeTransaction.query.filter(RechargeTransaction.storeId == storeId)
4765
    return query.all()
4766
 
7151 amit.gupta 4767
def get_recharge_trans(storeId, startdate,enddate, status):
4768
    if startdate == -1:
4769
        startdate = None
4770
    if enddate == -1:
4771
        enddate = None
4772
    if storeId== 0:
4773
        storeId = None
4774
    if status == 0:
4775
        status = None    
4776
 
4777
    query = RechargeTransaction.query
4778
    if storeId is not None:
4779
        query = query.filter(RechargeTransaction.storeId == storeId)
4780
    if status is not None:
4781
        query = query.filter(RechargeTransaction.status == status)
7169 anupam.sin 4782
 
4783
    if status == RechargeOrderStatus.RECHARGE_FAILED_REFUNDED :
4784
        query.filter(cast(RechargeTransaction.responseTime, DATE) == enddate)
7151 amit.gupta 4785
 
7169 anupam.sin 4786
    else :
4787
        if startdate is not None and enddate is not None:
4788
            startdate = to_py_date(startdate).date()
4789
            enddate = to_py_date(enddate).date()
4790
            if startdate == enddate:
4791
                query = query.filter(cast(RechargeTransaction.transactionTime, DATE) == enddate)
4792
            elif enddate < startdate:
4793
                query = query.filter(between(cast(RechargeTransaction.transactionTime, DATE), enddate, startdate))
4794
            else:
4795
                query = query.filter(between(cast(RechargeTransaction.transactionTime, DATE), startdate, enddate))
4796
        elif startdate is not None:
4797
            startdate = to_py_date(startdate).date()
4798
            query = query.filter(cast(RechargeTransaction.transactionTime, DATE) >= startdate)
4799
        elif enddate is not None:
4800
            enddate = to_py_date(enddate).date()
4801
            query = query.filter(cast(RechargeTransaction.transactionTime, DATE) <= enddate)
4802
 
7151 amit.gupta 4803
    return query.all()    
4804
 
7243 rajveer 4805
def update_recharge_transaction_status(id, status):
7127 rajveer 4806
    rechargeTransaction = RechargeTransaction.get_by(id=id)
7163 rajveer 4807
    if status in (RechargeOrderStatus.RECHARGE_FAILED_REFUNDED, RechargeOrderStatus.RECHARGE_FAILED):
4808
        rechargeTransaction.status = status
7243 rajveer 4809
        rechargeTransaction.responseTime = datetime.datetime.now() 
7127 rajveer 4810
 
4811
        store = HotspotStore.get_by(id=rechargeTransaction.storeId)
4812
        wallet = WalletForCompany.get_by(companyId=store.companyId)
4813
        wh = WalletHistoryForCompany()
4814
        wh.walletId = wallet.id
4815
        wh.amount = rechargeTransaction.amount
4816
        wh.transactionTime = rechargeTransaction.responseTime
4817
        wh.openingBal = wallet.amount
4818
        wh.closingBal = wallet.amount + wh.amount
4819
        wh.referenceNumber = rechargeTransaction.id 
4820
        wh.description = "Credited amount"
4821
 
4822
        wallet.amount = wallet.amount + rechargeTransaction.amount
4823
        store.availableLimit = store.availableLimit + rechargeTransaction.amount
4824
        store.collectedAmount = store.collectedAmount - rechargeTransaction.amount + rechargeTransaction.discount
4825
        session.commit()
7163 rajveer 4826
 
4827
    if status == RechargeOrderStatus.RECHARGE_SUCCESSFUL:
4828
        rechargeTransaction.status = RechargeOrderStatus.RECHARGE_SUCCESSFUL
4829
        rechargeTransaction.invoiceNumber = get_next_invoice_number(OrderType.RCH4HOTSPOT)
4830
        session.commit()
4831
 
4832
 
7073 anupam.sin 4833
def create_recharge_transaction(t_recharge):
7163 rajveer 4834
    dt = datetime.datetime.now() - datetime.timedelta(minutes=10)
4835
    txns = RechargeTransaction.query.filter(RechargeTransaction.deviceNum == t_recharge.deviceNum).filter(RechargeTransaction.transactionTime > dt).all()
4836
    if txns:
4837
        raise TransactionServiceException(898, "In last 10 minutes you had already recharged this mobile number. Please try after sometime.")
7073 anupam.sin 4838
    rechargeTransaction = RechargeTransaction()
4839
    rechargeTransaction.amount = t_recharge.amount
7096 anupam.sin 4840
    rechargeTransaction.circleId = t_recharge.circleId
7073 anupam.sin 4841
    rechargeTransaction.deviceNum = t_recharge.deviceNum
4842
    rechargeTransaction.deviceType = t_recharge.deviceType
4843
    rechargeTransaction.discount = t_recharge.discount
4844
    rechargeTransaction.email = t_recharge.email
4845
    rechargeTransaction.name = t_recharge.name
4846
    rechargeTransaction.cafNum = t_recharge.cafNum
4847
    rechargeTransaction.simNum = t_recharge.simNum
4848
    rechargeTransaction.isFrc = t_recharge.isFrc
4849
    rechargeTransaction.status = RechargeOrderStatus.INIT
4850
    rechargeTransaction.storeId = t_recharge.storeId
4851
    rechargeTransaction.transactionTime = datetime.datetime.now()
7075 rajveer 4852
    rechargeTransaction.operatorId = t_recharge.operatorId
4853
    rechargeTransaction.plan = t_recharge.plan
7080 anupam.sin 4854
    rechargeTransaction.ipAddress = t_recharge.ipAddress
7096 anupam.sin 4855
    rechargeTransaction.paymentAmount = t_recharge.paymentAmount
7139 amit.gupta 4856
    rechargeTransaction.payMethod = t_recharge.payMethod
7075 rajveer 4857
 
4858
    store = HotspotStore.get_by(id=rechargeTransaction.storeId)
7304 rajveer 4859
    if not rechargeTransaction.circleId:
4860
        rechargeTransaction.circleId = store.circleId
4861
 
7075 rajveer 4862
    wallet = WalletForCompany.get_by(companyId=store.companyId)
4863
    if store.availableLimit < rechargeTransaction.amount or wallet.amount < rechargeTransaction.amount:
4864
        raise TransactionServiceException(898, "Either wallet amount for company or available limit for store is less than recharge amount.")
7249 rajveer 4865
 
7075 rajveer 4866
    wh = WalletHistoryForCompany()
4867
    wh.walletId = wallet.id
4868
    wh.amount = -rechargeTransaction.amount
4869
    wh.transactionTime = rechargeTransaction.transactionTime
4870
    wh.openingBal = wallet.amount
4871
    wh.closingBal = wallet.amount + wh.amount
4872
    wh.description = "Debited amount"
4873
 
4874
    wallet.amount = wallet.amount - rechargeTransaction.amount
4875
    store.availableLimit = store.availableLimit - rechargeTransaction.amount
7076 rajveer 4876
    store.collectedAmount = store.collectedAmount + rechargeTransaction.amount - rechargeTransaction.discount 
7075 rajveer 4877
    session.commit()
4878
 
7249 rajveer 4879
    wh.referenceNumber = rechargeTransaction.id
4880
    session.commit()
4881
 
4882
 
7101 rajveer 4883
    strProviderCode = get_provider_code(rechargeTransaction.operatorId)
4884
    if rechargeTransaction.deviceType == 1:
4885
        rtype = 'MTP'
4886
    else:
4887
        rtype = 'RCH'
7369 rajveer 4888
    retStatus, retCode, spiceTID, description, aggTID, providerTID = RechargeService.rechargeDevice(rechargeTransaction.id, rtype, strProviderCode, rechargeTransaction.deviceNum, rechargeTransaction.amount, rechargeTransaction.plan)
7075 rajveer 4889
    rechargeTransaction.spiceTID = spiceTID
7369 rajveer 4890
    rechargeTransaction.aggTID = aggTID
4891
    rechargeTransaction.providerTID = providerTID
7075 rajveer 4892
    rechargeTransaction.responseTime = datetime.datetime.now()
4893
    rechargeTransaction.description = description
4894
    if retCode == '00' and retStatus == 'S':
4895
        rechargeTransaction.status = RechargeOrderStatus.RECHARGE_SUCCESSFUL
7096 anupam.sin 4896
        rechargeTransaction.invoiceNumber = get_next_invoice_number(OrderType.RCH4HOTSPOT)
7075 rajveer 4897
 
4898
    elif retCode in ('STO', 'US', 'UP') and retStatus == 'S':
4899
        rechargeTransaction.status = RechargeOrderStatus.RECHARGE_UNKNOWN
4900
    else:
4901
        rechargeTransaction.status = RechargeOrderStatus.RECHARGE_FAILED
4902
        if retCode in ('SVAI', 'SVIA', 'AI', 'IA', 'EAI', 'SVEAI'):
4903
            rechargeTransaction.description = "Invalid Amount"
4904
        elif retCode in ('ECL', 'SVECL', 'SCL'):
4905
            rechargeTransaction.description = "Customer Exceeded Daily Limit"
4906
        elif retCode in ('CI', 'ECI', 'ESP', 'SVCI', 'SVECI', 'SVESP', 'SV_ECI', 'SV ECI'):
4907
            rechargeTransaction.description = "Invalid Device Number"
4908
 
4909
        store = HotspotStore.get_by(id=rechargeTransaction.storeId)
4910
        wallet = WalletForCompany.get_by(companyId=store.companyId)
4911
        wh = WalletHistoryForCompany()
4912
        wh.walletId = wallet.id
4913
        wh.amount = rechargeTransaction.amount
4914
        wh.transactionTime = rechargeTransaction.responseTime
4915
        wh.openingBal = wallet.amount
4916
        wh.closingBal = wallet.amount + wh.amount
4917
        wh.referenceNumber = rechargeTransaction.id 
4918
        wh.description = "Credited amount"
4919
 
4920
        wallet.amount = wallet.amount + rechargeTransaction.amount
4921
        store.availableLimit = store.availableLimit + rechargeTransaction.amount
7076 rajveer 4922
        store.collectedAmount = store.collectedAmount - rechargeTransaction.amount + rechargeTransaction.discount
7075 rajveer 4923
 
4924
    session.commit()
4925
 
7073 anupam.sin 4926
    return rechargeTransaction
4927
 
7080 anupam.sin 4928
def get_frcs(circleId, operatorId):
7267 anupam.sin 4929
    query = FRC.query.filter(FRC.circleId == circleId)
4930
    if(operatorId > 0):
4931
        query = query.filter(FRC.operatorId == operatorId)
4932
 
4933
    frcs = query.all()
4934
 
7096 anupam.sin 4935
    if frcs is None:
4936
        return []
4937
    return frcs
7080 anupam.sin 4938
 
4939
def get_recharge_transaction(rechargeId):
4940
    recharge = RechargeTransaction.get_by(id = rechargeId)
4941
    if not recharge:
4942
        raise TransactionServiceException(108, "no such transaction")
4943
    return recharge
4944
 
7096 anupam.sin 4945
def get_hotspot_store(id, hotspotid):
4946
    store = None
4947
    if id > 0:
4948
        store = HotspotStore.query.filter(HotspotStore.id == id).first()
4949
    elif len(hotspotid) > 0:
4950
        store = HotspotStore.query.filter(HotspotStore.hotspotId == hotspotid).first()
4951
    else:
4952
        raise TransactionServiceException(119, 'No such store')
4953
    if store:
4954
        return store
4955
    else:
4956
        raise TransactionServiceException(119, 'No such store')
4957
 
4958
def get_circle(id, code):
4959
    circle = None
4960
    if id > 0:
4961
        circle = TelecomCircle.get_by(id = id)
4962
    elif len(code) > 0:
4963
        circle = TelecomCircle.get_by(code = code)
4964
    else:
4965
        raise TransactionServiceException(119, 'No such circle')
4966
    if circle:
4967
        return circle
4968
    else:
4969
        raise TransactionServiceException(119, 'No such circle')
4970
 
7109 anupam.sin 4971
def retrieve_hotspot_recharge_invoice(id):
4972
    recharge = RechargeTransaction.get_by(id = id)
7139 amit.gupta 4973
    filename = "/tmp/recharge" + str(recharge.invoiceNumber) + ".pdf"
7109 anupam.sin 4974
    operator = ServiceProvider.get_by(id = recharge.operatorId).name
4975
    amount = recharge.amount
4976
    telNum = "+91 " + str(recharge.deviceNum)
4977
    customerName = recharge.name
4978
    invNum = str(recharge.invoiceNumber)
4979
    billingTime = recharge.responseTime
7151 amit.gupta 4980
    payMethod = recharge.payMethod
4981
    return __printRechargeInvoice(filename, operator, amount, telNum, customerName, invNum, billingTime, payMethod)
7109 anupam.sin 4982
 
7190 amar.kumar 4983
def split_freebie_order(order_id, splitReason, shippingDate):
4984
    order = get_order(order_id)
4985
    freebie_order = Order()
4986
 
4987
    freebie_order.transaction = order.transaction
4988
 
4989
    freebie_order.customer_id = order.customer_id
4990
    freebie_order.customer_email = order.customer_email
4991
    freebie_order.customer_name = order.customer_name
4992
    freebie_order.customer_pincode = order.customer_pincode
4993
    freebie_order.customer_address1 = order.customer_address1
4994
    freebie_order.customer_address2 = order.customer_address2
4995
    freebie_order.customer_city = order.customer_city
4996
    freebie_order.customer_state = order.customer_state
4997
    freebie_order.customer_mobilenumber = order.customer_mobilenumber
4998
    freebie_order.total_weight = order.total_weight
4999
    freebie_order.total_amount = 0.01
5000
    freebie_order.status = OrderStatus.SUBMITTED_FOR_PROCESSING
5001
    freebie_order.statusDescription = "In Process";
5002
    freebie_order.created_timestamp = datetime.datetime.now()
5003
    freebie_order.cod = 0
5004
    freebie_order.orderType = OrderType.B2C
5005
    freebie_order.pickupStoreId = 0
5006
    freebie_order.otg = 0
5007
    freebie_order.insurer = 0
5008
    freebie_order.insuranceAmount = 0
5009
 
5010
    logistics_client = LogisticsClient().get_client()
5011
    logistics_info = logistics_client.getLogisticsInfo(order.customer_pincode, 1, DeliveryType.PREPAID, PickUpType.COURIER)
5012
    freebie_order.logistics_provider_id = logistics_info.providerId;
5013
    freebie_order.tracking_id = logistics_info.airway_billno
5014
    freebie_order.airwaybill_no = logistics_info.airway_billno
5015
    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)  
5016
    freebie_order.promised_delivery_time = order.promised_delivery_time
5017
    freebie_order.expected_shipping_time = to_py_date(shippingDate)
5018
    freebie_order.promised_shipping_time = order.promised_shipping_time
5019
 
5020
    inventory_client = InventoryClient().get_client()
7198 amar.kumar 5021
    item_availability = inventory_client.getItemAvailabilityAtLocation(order.freebieItemId,1)
7190 amar.kumar 5022
    freebie_order.warehouse_id = item_availability[2]
7303 amar.kumar 5023
    freebie_order.fulfilmentWarehouseId = item_availability[0]
7190 amar.kumar 5024
 
5025
    catalog_client = CatalogClient().get_client()
5026
    item = catalog_client.getItem(order.freebieItemId)
5027
    freebie_order.total_weight = item.weight
5028
 
5029
    litem = LineItem()
5030
    litem.item_id = item.id
5031
    litem.productGroup = item.productGroup
5032
    litem.brand = item.brand
5033
    litem.model_number = item.modelNumber
5034
    litem.model_name = item.modelName
5035
    litem.color = item.color
5036
    litem.extra_info = "Freebie Order for Order ID " + str(order.id)
5037
    litem.quantity = 1
5038
    litem.unit_price = 0.01
5039
    litem.unit_weight = item.weight
5040
    litem.total_price = 0.01
5041
    litem.total_weight = item.weight
5042
    litem.vatRate = 5.0
5043
 
5044
    freebie_order.lineitems.append(litem)
7198 amar.kumar 5045
    order.freebieItemId = 0
7190 amar.kumar 5046
    session.commit()
7198 amar.kumar 5047
    order.lineitems[0].extra_info = "Parent Order for Order ID " + str(freebie_order.id)
7190 amar.kumar 5048
 
7198 amar.kumar 5049
    inventory_client = InventoryClient().get_client()   
5050
    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)
7190 amar.kumar 5051
    parentOrderAttribute = Attribute()
5052
    parentOrderAttribute.orderId = freebie_order.id
5053
    parentOrderAttribute.name = "parentOrderIdForFreebie"
5054
    parentOrderAttribute.value = str(order.id)
5055
 
5056
    freebieOrderAttribute = Attribute()
5057
    freebieOrderAttribute.orderId = order.id
5058
    freebieOrderAttribute.name = "freebieOrderId"
5059
    freebieOrderAttribute.value = str(freebie_order.id)
5060
    session.commit()
5061
 
7198 amar.kumar 5062
    return to_t_order(freebie_order)
7190 amar.kumar 5063
 
7151 amit.gupta 5064
def __printRechargeInvoice(filename, operator, amount, telNum, customerName, invNum, billingTime, payMethod): 
7109 anupam.sin 5065
    PAGE_HEIGHT=defaultPageSize[1];
5066
    styles = getSampleStyleSheet()
5067
    styles.add(ParagraphStyle(name='prologue', alignment=TA_CENTER, fontName="Courier", rightIndent = 5, fontSize=10), alias='sH')
5068
    styles.add(ParagraphStyle(name='text', alignment=TA_JUSTIFY, fontName="Courier", fontSize=10), alias='text')
5069
    styles.add(ParagraphStyle(name='line', alignment=TA_CENTER, fontName="Courier", fontSize=10), alias='line')
5070
    styles.add(ParagraphStyle(name='epilogue', alignment=TA_CENTER, fontName="Courier", leftIndent = 30, rightIndent=36, fontSize=10), alias='ep')
7096 anupam.sin 5071
 
7109 anupam.sin 5072
    Story = []
5073
    prologueStyle = styles["prologue"]
5074
    lineStyle = styles["line"]
5075
    textStyle = styles["text"]
5076
    epilogueStyle = styles["epilogue"]
7096 anupam.sin 5077
 
7109 anupam.sin 5078
    doc = BaseDocTemplate(filename,showBoundary=0)
5079
 
5080
    #Two Columns
5081
    frame1 = Frame(58, doc.bottomMargin, doc.width/2 + 25, doc.height + 7, id='col1')
5082
 
5083
 
5084
 
5085
    Story.append(Paragraph("""Spice Retail Limited<br></br>
5086
        C/O,PIBCO LIMITED,Basement,Punjsons<br></br>
5087
        2,Kalkaji Industrial Area,New Delhi<br></br>
5088
          .<br></br>
5089
        TIN NO. 07430284979<br></br>
5090
        Service Tax No:AAACM0294PST001<br></br><br></br><br></br>""", prologueStyle))
5091
    drawLine(Story, lineStyle)
5092
 
5093
    Story.append(Paragraph('{0:7s}{1:>11s}{2:  %d/%m/%Y  %H:%M:%S}'.format("INV NO:", invNum, billingTime).replace(" ", "&nbsp;"), textStyle))
5094
    drawLine(Story, lineStyle)
5095
 
5096
    Story.append(Paragraph("{0:<6s}{1:<34s}".format("NAME:", customerName).replace(" ", "&nbsp;"), textStyle))
5097
    Story.append(Paragraph("{0:<9s}{1:<31s}".format("TEL NO.:", telNum).replace(" ", "&nbsp;"), textStyle))
7151 amit.gupta 5098
    Story.append(Paragraph("{0:<9s}{1:<31s}".format("PAYMENT MODE:", PayMethod._VALUES_TO_NAMES[payMethod]).replace(" ", "&nbsp;"), textStyle))
7109 anupam.sin 5099
    drawLine(Story, lineStyle)
5100
 
5101
    Story.append(Paragraph(('{0:<16s}{1:>13s}{2:11.2f}').format(operator, "RECHARGE", amount).replace(' ', '&nbsp;'),textStyle))
5102
    drawLine(Story, lineStyle)
5103
    doc.addPageTemplates([PageTemplate(id='TwoCol',frames=[frame1]), ])
5104
 
5105
    #start the construction of the pdf
5106
    doc.build(Story)
5107
 
5108
    try:
5109
        fileToSend = open(filename, "rb")
5110
        pdfFile = fileToSend.read()
5111
    except:
5112
        return bin(0)
5113
 
5114
    return pdfFile
5115
 
7172 anupam.sin 5116
def get_recharge_transactions_by_number(number, storeId):
7169 anupam.sin 5117
    query = RechargeTransaction.query.filter(RechargeTransaction.deviceNum == number)
7172 anupam.sin 5118
    query = query.filter(RechargeTransaction.storeId == storeId)
7169 anupam.sin 5119
    return query.all()
5120
 
5121
def update_hotspot_store_password(storeId, password):
5122
    store = None
5123
    if password is None:
5124
        return False
5125
    if storeId:
5126
        store = HotspotStore.query.filter(HotspotStore.id == storeId).first()
5127
    if store:
5128
        store.password = password
5129
        session.commit()
5130
        return True
5131
    return False
5132
 
7263 anupam.sin 5133
def get_source_detail(source):
5134
    detail = SourceDetail.get_by(id=source)
5135
    if not detail:
5136
        raise TransactionServiceException(108, "no such source")
5137
    return detail
5138
 
7267 anupam.sin 5139
def get_all_circles():
5140
    circles = TelecomCircle.query.all();
5141
    if not circles:
5142
        circles = []
5143
    return circles 
5144
 
5145
def delete_frcs(frcIdsToDelete):
5146
    toReturn = False
5147
    if frcIdsToDelete:
5148
        for frcId in frcIdsToDelete:
5149
            frc = FRC.get_by(id = frcId)
5150
            if frc:
5151
                frc.delete()
5152
                toReturn = True
5153
        session.commit()
5154
        return toReturn
5155
    else:
5156
        return toReturn
5157
 
7285 rajveer 5158
def topup_company_wallet(companyId, amount):
5159
    wallet = WalletForCompany.query.filter(WalletForCompany.id == companyId).with_lockmode("update").one()
5160
    company = Company.get_by(id = companyId)
5161
    wh = WalletHistoryForCompany()
5162
    wh.walletId = wallet.id
5163
    wh.openingBal = wallet.amount
5164
    wh.closingBal = wallet.amount +  amount
5165
    wh.amount = amount
5166
    wh.transactionTime = datetime.datetime.now()
5167
    wh.referenceNumber =  get_next_invoice_number(OrderType.WALLETCREDIT)
5168
    wh.description = "Wallet Credited"
5169
 
5170
    wallet.amount += amount
5171
    session.commit()
5172
    mail("cnc.center@shop2020.in", "5h0p2o2o", ["rajveer.singh@shop2020.in", "anupam.singh@shop2020.in", "Ashwani.Kumar@spiceretail.co.in","parveen.mittal@spiceretail.co.in","pardeep.panwar@spiceretail.co.in","gagan.sharma@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.", "", [], [], [])
5173
    return wallet.amount
7267 anupam.sin 5174
 
7285 rajveer 5175
def get_wallet_balance_for_company(companyId):
5176
    return WalletForCompany.get_by(companyId = companyId).amount
5177
 
7311 kshitij.so 5178
def add_amazon_order(amazonOrder):
5179
    amazon_order = AmazonOrder()
5180
    amazon_order.orderId = amazonOrder.orderId
5181
    amazon_order.amazonOrderCode = amazonOrder.amazonOrderCode
5182
    amazon_order.amazonOrderItemCode = amazonOrder.amazonOrderItemCode
5183
    amazon_order.transactionId = amazonOrder.transactionId
5184
    amazon_order.item_id= amazonOrder.item_id
5185
    amazon_order.status= amazonOrder.status
5186
    session.commit()
5187
 
7322 vikram.rag 5188
def update_amazon_order_status(order_id,status):
7311 kshitij.so 5189
    try:
5190
        row = AmazonOrder.get_by(orderId=order_id)
5191
        row.status=status
5192
        result=True
5193
    except:
5194
        result=False
5195
    finally:
5196
        session.commit()
5197
        return result
5198
 
5199
def get_amazon_orders_marked_sent():
7322 vikram.rag 5200
    return AmazonOrder.query.filter(AmazonOrder.status=='Acknowledgement-Sent').all()
7311 kshitij.so 5201
 
5202
def get_amazon_orders_shipped(interval):
5203
    amazonShippedOrders = []
5204
    toDate = datetime.datetime.now()
5205
    fromDate = toDate-timedelta(days = interval-1, hours=toDate.hour, minutes=toDate.minute, seconds=toDate.second)
5206
    orders = get_amazon_orders_marked_sent()
5207
    for order in orders:
5208
        row = Order.query.filter(Order.shipping_timestamp.between (fromDate,toDate)).filter(Order.id==order.orderId).first()
7314 kshitij.so 5209
        if row is None:
5210
            continue
7311 kshitij.so 5211
        amazonShippedOrders.append(to_t_order(row))
5212
    return amazonShippedOrders
5213
 
5214
def get_amazon_orders_cancelled(interval):
5215
    amazonCancelledOrders = []
5216
    toDate = datetime.datetime.now()
5217
    fromDate = toDate-timedelta(days = interval-1, hours=toDate.hour, minutes=toDate.minute, seconds=toDate.second)
5218
    orders = get_amazon_orders_marked_sent()
5219
    for order in orders:
5220
        row = Order.query.filter(Order.refund_timestamp.between (fromDate,toDate)).filter(Order.id==order.orderId).first()
7314 kshitij.so 5221
        if row is None:
5222
            continue
7311 kshitij.so 5223
        if ( row.status == 15 or row.status == 18 or row.status == 34 ):
5224
            amazonCancelledOrders.append(to_t_order(row))
5225
    return amazonCancelledOrders        
7322 vikram.rag 5226
 
5227
def get_amazon_order(order_id):
5228
    return AmazonOrder.get_by(orderId=order_id)
5229
 
7311 kshitij.so 5230
 
7343 anupam.sin 5231
def get_orders_for_store(orderId, storeId, startDate, endDate, statuses):
5232
    orders = []
5233
    query = Order.query
5234
    if storeId < 1:
5235
        return orders
5236
    elif orderId > 0:
5237
        query = query.filter(Order.id == orderId)
5238
    else :
5239
        if startDate:
5240
            query = query.filter(cast(Order.created_timestamp, DATE) >= startDate.date())
5241
 
5242
        if endDate:
5243
            query = query.filter(cast(Order.created_timestamp, DATE) <= endDate.date())
5244
 
5245
        if len(statuses) > 0:
5246
            query = query.filter(Order.status.in_(statuses))
5247
 
5248
    orders = query.filter(Order.storeId == storeId).all()
5249
    return orders
5250
 
7386 anupam.sin 5251
def get_store_order_advance_invoice(orderId, storeId):
7343 anupam.sin 5252
    order = Order.get_by(id = orderId)
7386 anupam.sin 5253
    storeOrderDetail = StoreOrderDetail.query.filter(StoreOrderDetail.orderId == orderId).filter(StoreOrderDetail.storeId == storeId).first()
7343 anupam.sin 5254
    filename = "/tmp/recharge" + str(order.id) + ".pdf"
7346 anupam.sin 5255
    modelName = "&nbsp;"
5256
    modelNumber = "&nbsp;"
5257
    color = "&nbsp;"
5258
    if order.lineitems[0].model_name:
5259
        modelName = modelName + order.lineitems[0].model_name
5260
    if order.lineitems[0].model_number:
5261
        modelNumber = modelNumber + order.lineitems[0].model_number
5262
    if order.lineitems[0].color:
5263
        color = color + order.lineitems[0].color
5264
 
5265
    product = order.lineitems[0].brand +  modelName + modelNumber + color
7386 anupam.sin 5266
    advanceAmount = order.advanceAmount
7343 anupam.sin 5267
    totalAmount = order.total_amount
7346 anupam.sin 5268
    delivery = order.expected_delivery_time
7386 anupam.sin 5269
 
7343 anupam.sin 5270
    customerName = order.customer_name
7386 anupam.sin 5271
    customerAdd1 = order.customer_address1
5272
    customerAdd2 = order.customer_address2
5273
    customerCity = order.customer_city
5274
    customerState = order.customer_state
5275
    customerMobile = order.customer_mobilenumber
5276
    customerPin = order.customer_pincode
5277
 
5278
    mode = ""
5279
    if storeOrderDetail.cashAmount > 0 and storeOrderDetail.cardAmount > 0:
5280
        mode = "CASH + CARD"
5281
    elif storeOrderDetail.cashAmount > 0:
5282
        mode = "CASH"
5283
    elif storeOrderDetail.cardAmount > 0:
5284
        mode = "CARD"
5285
 
7343 anupam.sin 5286
    #payMethod = recharge.payMethod
7386 anupam.sin 5287
#    if order.status == 15 or order.status == 34:
5288
#        return __printStoreOrderAdvanceInvoice(filename, product, advanceAmount, totalAmount, customerName, delivery, mode, customerAdd1, customerAdd2, customerCity, customerState, customerMobile, customerPin)
5289
    return __printStoreOrderAdvanceInvoice(filename, product, advanceAmount, totalAmount, customerName, delivery, mode, customerAdd1, customerAdd2, customerCity, customerState, customerMobile, customerPin)
7343 anupam.sin 5290
 
5291
 
7386 anupam.sin 5292
def __printStoreOrderAdvanceInvoice(filename, product, advanceAmount, totalAmount, customerName, delivery, mode, customerAdd1, customerAdd2, customerCity, customerState, customerMobile, customerPin): 
7343 anupam.sin 5293
    PAGE_HEIGHT=defaultPageSize[1];
5294
    styles = getSampleStyleSheet()
5295
    styles.add(ParagraphStyle(name='prologue', alignment=TA_CENTER, fontName="Courier", rightIndent = 5, fontSize=10), alias='sH')
5296
    styles.add(ParagraphStyle(name='text', alignment=TA_JUSTIFY, fontName="Courier", fontSize=10), alias='text')
5297
    styles.add(ParagraphStyle(name='line', alignment=TA_CENTER, fontName="Courier", fontSize=10), alias='line')
5298
    styles.add(ParagraphStyle(name='epilogue', alignment=TA_CENTER, fontName="Courier", leftIndent = 30, rightIndent=36, fontSize=10), alias='ep')
5299
 
5300
    Story = []
5301
    prologueStyle = styles["prologue"]
5302
    lineStyle = styles["line"]
5303
    textStyle = styles["text"]
5304
    epilogueStyle = styles["epilogue"]
5305
 
5306
    doc = BaseDocTemplate(filename,showBoundary=0)
5307
 
5308
    #Two Columns
5309
    frame1 = Frame(58, doc.bottomMargin, doc.width/2 + 25, doc.height + 7, id='col1')
5310
 
5311
 
7386 anupam.sin 5312
    ############### TODO ###############################################################
7343 anupam.sin 5313
    Story.append(Paragraph("""Spice Retail Limited<br></br>
5314
        C/O,PIBCO LIMITED,Basement,Punjsons<br></br>
5315
        2,Kalkaji Industrial Area,New Delhi<br></br>
5316
          .<br></br>
5317
        TIN NO. 07430284979<br></br>
5318
        Service Tax No:AAACM0294PST001<br></br><br></br><br></br>""", prologueStyle))
7386 anupam.sin 5319
    ############### ADDRESS TO BE DYNAMIC ##############################################
5320
 
7343 anupam.sin 5321
    drawLine(Story, lineStyle)
5322
 
7386 anupam.sin 5323
    Story.append(Paragraph("{0:^39s}".format("DELIVERY ADDRESS").replace(" ", "&nbsp;"), textStyle))
5324
    drawLine(Story, lineStyle)
5325
    Story.append(Paragraph(customerAdd1, textStyle))
5326
    if len(customerAdd2) > 0:
5327
        Story.append(Paragraph(customerAdd2, textStyle))
5328
 
5329
    Story.append(Paragraph(customerCity, textStyle))
5330
    Story.append(Paragraph(customerState + " - " + customerPin, textStyle))
5331
    drawLine(Story, lineStyle)
7343 anupam.sin 5332
 
5333
    Story.append(Paragraph("{0:<6s}{1:<34s}".format("NAME:", customerName).replace(" ", "&nbsp;"), textStyle))
7386 anupam.sin 5334
    Story.append(Paragraph("{0:<10s}{1:<29s}".format("MOBILE:", customerMobile).replace(" ", "&nbsp;"), textStyle))
7343 anupam.sin 5335
    Story.append(Paragraph("{0:<15s}{1:  %d/%m/%Y}".format("EXP DELIVERY:", delivery).replace(" ", "&nbsp;"), textStyle))
7386 anupam.sin 5336
    Story.append(Paragraph("{0:<15s}{1:<25s}".format("PAYMENT MODE:", mode).replace(" ", "&nbsp;"), textStyle))
7343 anupam.sin 5337
 
5338
    drawLine(Story, lineStyle)
7346 anupam.sin 5339
    Story.append(Paragraph("{0:^39s}".format("PRODUCT NAME").replace(" ", "&nbsp;"), textStyle))
7343 anupam.sin 5340
    drawLine(Story, lineStyle)
5341
    Story.append(Paragraph("{0:<39s}".format(product).replace(" ", "&nbsp;"), textStyle))
5342
    drawLine(Story, lineStyle)
5343
 
5344
    Story.append(Paragraph(('{0:<20s}{1:>19.2f}').format("TOTAL PRICE: ", totalAmount).replace(' ', '&nbsp;'),textStyle))
7386 anupam.sin 5345
    Story.append(Paragraph(('{0:<20s}{1:>19.2f}').format("ADVANCE AMOUNT: ", advanceAmount).replace(' ', '&nbsp;'),textStyle))
5346
    Story.append(Paragraph(('{0:<20s}{1:>19.2f}').format("BALANCE TO BE PAID: ", (totalAmount - advanceAmount)).replace(' ', '&nbsp;'),textStyle))
7343 anupam.sin 5347
 
5348
    drawLine(Story, lineStyle)
7386 anupam.sin 5349
    Story.append(Paragraph(('{0:<20s}{1:>19s}').format("Customer care : ", "0120-6744700").replace(' ', '&nbsp;'),textStyle))
7346 anupam.sin 5350
    drawLine(Story, lineStyle)
7386 anupam.sin 5351
    drawLine(Story, lineStyle)
7343 anupam.sin 5352
 
7386 anupam.sin 5353
    Story.append(Paragraph("Note:", textStyle))                                        
5354
    Story.append(Paragraph("* In case of cancellation of order on customer request, 10% of product amount subject to minimum Rs 500/- shall be deducted by Spice Retail Limited as cancellation charges. Customer shall provide original copy of 'Advance Receipt' to get the balance amount as refund",textStyle))                                        
5355
    Story.append(Paragraph("* In case of cancellation of order other than customer request, original copy of 'Advance Receipt' shall be provided by customer to get the refund",textStyle))                                        
5356
    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))                                         
5357
    Story.append(Paragraph("* The product as mentioned above shall be made available to the customer, subject to its availability from the manufacturer",textStyle))                                        
5358
 
5359
 
7343 anupam.sin 5360
    doc.addPageTemplates([PageTemplate(id='TwoCol',frames=[frame1]), ])
5361
 
5362
    #start the construction of the pdf
5363
    doc.build(Story)
5364
 
5365
    try:
5366
        fileToSend = open(filename, "rb")
5367
        pdfFile = fileToSend.read()
5368
    except:
5369
        return bin(0)
5370
 
5371
    return pdfFile
5372
 
7370 anupam.sin 5373
def add_frc(circle, operatorId, denomination, maxDiscount):
7371 anupam.sin 5374
    frc = FRC.query.filter(FRC.circleId == circle).filter(FRC.operatorId == operatorId).filter(FRC.denomination == denomination).first()
7370 anupam.sin 5375
    if frc:
5376
        frc.maxDiscount = maxDiscount
5377
    else:
5378
        frc = FRC()
5379
        frc.circleId = circle
5380
        frc.denomination = denomination
5381
        frc.maxDiscount = maxDiscount
5382
        frc.operatorId = operatorId
5383
    session.commit()
5384
    return True 
5385
 
7371 anupam.sin 5386
def add_series(circle, operatorId, series):
5387
    operatorSeriesObject = OperatorSeries.query.filter(OperatorSeries.series == series).first()
5388
    if operatorSeriesObject:
5389
        circleName = TelecomCircle.get_by(id = operatorSeriesObject.circleId).name
5390
        operatorName = ServiceProvider.get_by(id = operatorSeriesObject.operatorId).name
5391
        return "Series already exists for : " + operatorName + " in circle : " + circleName
5392
    else :
5393
        operatorSeriesObject = OperatorSeries()
5394
        operatorSeriesObject.series = series
5395
        operatorSeriesObject.circleId = circle
5396
        operatorSeriesObject.operatorId = operatorId
5397
        session.commit()
5398
        return "Successfully saved"
7386 anupam.sin 5399
 
5400
 
5401
def save_store_order_detail(thrift_storeOrderDetail):
5402
    txnId = thrift_storeOrderDetail.orderId
5403
    txn = Transaction.get_by(id=txnId)
5404
    oid = txn.orders[0].id
5405
    ds_storeOrderDetail = StoreOrderDetail()
5406
    ds_storeOrderDetail.orderId = oid
5407
    ds_storeOrderDetail.advanceAmount = thrift_storeOrderDetail.advanceAmount
5408
    ds_storeOrderDetail.cardAmount = thrift_storeOrderDetail.cardAmount
5409
    ds_storeOrderDetail.cashAmount = thrift_storeOrderDetail.cashAmount
5410
    ds_storeOrderDetail.storeId = thrift_storeOrderDetail.storeId
5411
    ds_storeOrderDetail.payStatus = thrift_storeOrderDetail.payStatus
5412
    session.commit()
5413
    return True
5414
 
5415
def get_store_order_detail(orderId, storeId):
5416
    storeOrderDetail = StoreOrderDetail.query.filter(StoreOrderDetail.orderId == orderId).filter(StoreOrderDetail.storeId == storeId).first()
5417
    if storeOrderDetail:
5418
        return storeOrderDetail
5419
    else:
5420
        return StoreOrderDetail()
5421
 
5422
def get_all_edc_banks():
5423
    allBankNames = []
5424
    edcBanks = EdcBank.query.all();
5425
    for bank in edcBanks:
5426
        allBankNames.append(bank.name)
5427
    return allBankNames
5428
 
6915 anupam.sin 5429
if __name__ == '__main__':
6980 anupam.sin 5430
    print 'helllo'