Subversion Repositories SmartDukaan

Rev

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

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