Subversion Repositories SmartDukaan

Rev

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